Repository: jbarczak/Pyramid
Branch: master
Commit: 397118665161
Files: 357
Total size: 2.6 MB
Directory structure:
gitextract_1e9qi61g/
├── .gitattributes
├── .gitignore
├── .gitmodules
├── Distribute.bat
├── LICENSE.txt
├── README.md
├── shims/
│ └── atidxx_shim/
│ ├── ShimDLL.cpp
│ ├── ShimDLL.sln
│ ├── ShimDLL.vcxproj
│ └── elf.h
├── src/
│ ├── App.config
│ ├── Backends/
│ │ ├── AMDDriverBackend.cs
│ │ ├── AMDDriverResultsPanel.Designer.cs
│ │ ├── AMDDriverResultsPanel.cs
│ │ ├── AMDDriverResultsPanel.resx
│ │ ├── CodeXLAnalysisPanel.Designer.cs
│ │ ├── CodeXLAnalysisPanel.cs
│ │ ├── CodeXLAnalysisPanel.resx
│ │ ├── CodeXLBackend.cs
│ │ ├── CodeXLResultsPanel.Designer.cs
│ │ ├── CodeXLResultsPanel.cs
│ │ ├── CodeXLResultsPanel.resx
│ │ ├── FXCBackend.cs
│ │ ├── FXCResultsPanel.Designer.cs
│ │ ├── FXCResultsPanel.cs
│ │ ├── FXCResultsPanel.resx
│ │ ├── GLSLOptimizerBackend.cs
│ │ ├── GLSlangBackend.cs
│ │ ├── GLSlangResultsPanel.Designer.cs
│ │ ├── GLSlangResultsPanel.cs
│ │ ├── GLSlangResultsPanel.resx
│ │ ├── IBackend.cs
│ │ ├── IntelShaderAnalyzerBackend.cs
│ │ ├── IntelShaderAnalyzerResultsPanel.Designer.cs
│ │ ├── IntelShaderAnalyzerResultsPanel.cs
│ │ ├── IntelShaderAnalyzerResultsPanel.resx
│ │ ├── MaliSCBackend.cs
│ │ ├── MaliSCResultsPanel.Designer.cs
│ │ ├── MaliSCResultsPanel.cs
│ │ ├── MaliSCResultsPanel.resx
│ │ ├── PVRResultsPanel.Designer.cs
│ │ ├── PVRResultsPanel.cs
│ │ ├── PVRResultsPanel.resx
│ │ ├── PowerVRBackend.cs
│ │ └── RGABackend.cs
│ ├── GLSLOptimizer.cs
│ ├── GLSLTypes.cs
│ ├── GLSlang.cs
│ ├── HLSLTypes.cs
│ ├── IAMDDriver.cs
│ ├── ICSharpCode.TextEditor/
│ │ └── Project/
│ │ ├── Configuration/
│ │ │ └── AssemblyInfo.cs
│ │ ├── GlobalAssemblyInfo.cs
│ │ ├── ICSharpCode.TextEditor.csproj
│ │ ├── Resources/
│ │ │ ├── CPP-Mode.xshd
│ │ │ ├── GLSL-Mode.xshd
│ │ │ ├── HLSL-Mode.xshd
│ │ │ ├── ICSharpCode.TextEditor.snk
│ │ │ ├── Mode.xsd
│ │ │ ├── RightArrow.cur
│ │ │ └── SyntaxModes.xml
│ │ └── Src/
│ │ ├── Actions/
│ │ │ ├── BookmarkActions.cs
│ │ │ ├── CaretActions.cs
│ │ │ ├── ClipBoardActions.cs
│ │ │ ├── FindReplaceAction.cs
│ │ │ ├── FoldActions.cs
│ │ │ ├── FormatActions.cs
│ │ │ ├── HomeEndActions.cs
│ │ │ ├── IEditAction.cs
│ │ │ ├── MiscActions.cs
│ │ │ └── SelectionActions.cs
│ │ ├── Document/
│ │ │ ├── AbstractSegment.cs
│ │ │ ├── BookmarkManager/
│ │ │ │ ├── Bookmark.cs
│ │ │ │ ├── BookmarkEventHandler.cs
│ │ │ │ ├── BookmarkManager.cs
│ │ │ │ └── BookmarkManagerMemento.cs
│ │ │ ├── DefaultDocument.cs
│ │ │ ├── DefaultTextEditorProperties.cs
│ │ │ ├── DocumentEventArgs.cs
│ │ │ ├── DocumentFactory.cs
│ │ │ ├── FoldingStrategy/
│ │ │ │ ├── FoldMarker.cs
│ │ │ │ ├── FoldingManager.cs
│ │ │ │ ├── IFoldingStrategy.cs
│ │ │ │ └── IndentFoldingStrategy.cs
│ │ │ ├── FormattingStrategy/
│ │ │ │ ├── DefaultFormattingStrategy.cs
│ │ │ │ └── IFormattingStrategy.cs
│ │ │ ├── HighlightingStrategy/
│ │ │ │ ├── DefaultHighlightingStrategy.cs
│ │ │ │ ├── FontContainer.cs
│ │ │ │ ├── HighlightBackground.cs
│ │ │ │ ├── HighlightColor.cs
│ │ │ │ ├── HighlightInfo.cs
│ │ │ │ ├── HighlightRuleSet.cs
│ │ │ │ ├── HighlightingColorNotFoundException.cs
│ │ │ │ ├── HighlightingDefinitionInvalidException.cs
│ │ │ │ ├── HighlightingDefinitionParser.cs
│ │ │ │ ├── HighlightingManager.cs
│ │ │ │ ├── HighlightingStrategyFactory.cs
│ │ │ │ ├── IHighlightingStrategy.cs
│ │ │ │ ├── NextMarker.cs
│ │ │ │ ├── PrevMarker.cs
│ │ │ │ ├── Span.cs
│ │ │ │ ├── SpanStack.cs
│ │ │ │ ├── SyntaxModes/
│ │ │ │ │ ├── FileSyntaxModeProvider.cs
│ │ │ │ │ ├── ISyntaxModeFileProvider.cs
│ │ │ │ │ ├── ResourceSyntaxModeProvider.cs
│ │ │ │ │ └── SyntaxMode.cs
│ │ │ │ └── TextWord.cs
│ │ │ ├── IDocument.cs
│ │ │ ├── ISegment.cs
│ │ │ ├── ITextEditorProperties.cs
│ │ │ ├── LineManager/
│ │ │ │ ├── DeferredEventList.cs
│ │ │ │ ├── LineManager.cs
│ │ │ │ ├── LineManagerEventArgs.cs
│ │ │ │ ├── LineSegment.cs
│ │ │ │ └── LineSegmentTree.cs
│ │ │ ├── MarkerStrategy/
│ │ │ │ ├── MarkerStrategy.cs
│ │ │ │ └── TextMarker.cs
│ │ │ ├── Selection/
│ │ │ │ ├── ColumnRange.cs
│ │ │ │ ├── DefaultSelection.cs
│ │ │ │ ├── ISelection.cs
│ │ │ │ └── SelectionManager.cs
│ │ │ ├── TextAnchor.cs
│ │ │ ├── TextBufferStrategy/
│ │ │ │ ├── GapTextBufferStrategy.cs
│ │ │ │ ├── ITextBufferStrategy.cs
│ │ │ │ └── StringTextBufferStrategy.cs
│ │ │ ├── TextLocation.cs
│ │ │ └── TextUtilities.cs
│ │ ├── Gui/
│ │ │ ├── AbstractMargin.cs
│ │ │ ├── BracketHighlighter.cs
│ │ │ ├── BrushRegistry.cs
│ │ │ ├── Caret.cs
│ │ │ ├── CompletionWindow/
│ │ │ │ ├── AbstractCompletionWindow.cs
│ │ │ │ ├── CodeCompletionListView.cs
│ │ │ │ ├── CodeCompletionWindow.cs
│ │ │ │ ├── DeclarationViewWindow.cs
│ │ │ │ ├── ICompletionData.cs
│ │ │ │ └── ICompletionDataProvider.cs
│ │ │ ├── DrawableLine.cs
│ │ │ ├── FindReplaceForm/
│ │ │ │ ├── FindAndReplaceForm.Designer.cs
│ │ │ │ ├── FindAndReplaceForm.cs
│ │ │ │ └── FindAndReplaceForm.resx
│ │ │ ├── FoldMargin.cs
│ │ │ ├── GutterMargin.cs
│ │ │ ├── HRuler.cs
│ │ │ ├── IconBarMargin.cs
│ │ │ ├── Ime.cs
│ │ │ ├── InsightWindow/
│ │ │ │ ├── IInsightDataProvider.cs
│ │ │ │ └── InsightWindow.cs
│ │ │ ├── TextArea.cs
│ │ │ ├── TextAreaClipboardHandler.cs
│ │ │ ├── TextAreaControl.cs
│ │ │ ├── TextAreaDragDropHandler.cs
│ │ │ ├── TextAreaMouseHandler.cs
│ │ │ ├── TextAreaUpdate.cs
│ │ │ ├── TextEditorControl.cs
│ │ │ ├── TextEditorControlBase.cs
│ │ │ ├── TextView.cs
│ │ │ └── ToolTipRequestEventArgs.cs
│ │ ├── Undo/
│ │ │ ├── IUndoableOperation.cs
│ │ │ ├── UndoQueue.cs
│ │ │ ├── UndoStack.cs
│ │ │ ├── UndoableDelete.cs
│ │ │ ├── UndoableInsert.cs
│ │ │ └── UndoableReplace.cs
│ │ └── Util/
│ │ ├── AugmentableRedBlackTree.cs
│ │ ├── CheckedList.cs
│ │ ├── FileReader.cs
│ │ ├── LoggingService.cs
│ │ ├── LookupTable.cs
│ │ ├── MouseWheelHandler.cs
│ │ ├── RedBlackTreeIterator.cs
│ │ ├── RtfWriter.cs
│ │ ├── TextUtility.cs
│ │ ├── TipPainter.cs
│ │ ├── TipPainterTools.cs
│ │ ├── TipSection.cs
│ │ ├── TipSpacer.cs
│ │ ├── TipSplitter.cs
│ │ ├── TipText.cs
│ │ └── WeakCollection.cs
│ ├── IIncludeHandler.cs
│ ├── IWrapper.cs
│ ├── IncludeHandler.cs
│ ├── LanguageTypes.cs
│ ├── Languages/
│ │ ├── GLSLLanguage.cs
│ │ ├── GLSLOptionsPanel.Designer.cs
│ │ ├── GLSLOptionsPanel.cs
│ │ ├── GLSLOptionsPanel.resx
│ │ ├── HLSLLanguage.cs
│ │ ├── HLSLOptionsPanel.Designer.cs
│ │ ├── HLSLOptionsPanel.cs
│ │ ├── HLSLOptionsPanel.resx
│ │ ├── ICompileOptionsPanel.cs
│ │ └── ILanguage.cs
│ ├── MainUI/
│ │ ├── AboutBox.Designer.cs
│ │ ├── AboutBox.cs
│ │ ├── AboutBox.resx
│ │ ├── MainForm.Designer.cs
│ │ ├── MainForm.cs
│ │ ├── MainForm.resx
│ │ ├── OptionsScreen.Designer.cs
│ │ ├── OptionsScreen.cs
│ │ └── OptionsScreen.resx
│ ├── Options.cs
│ ├── Program.cs
│ ├── Properties/
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ ├── Resources.resx
│ │ ├── Settings.Designer.cs
│ │ └── Settings.settings
│ ├── Pyramid.csproj
│ ├── Pyramid.sln
│ ├── PyramidTypes.csproj
│ ├── SPIRV.cs
│ ├── Scrutinizer/
│ │ ├── Analysis/
│ │ │ └── Algorithms.cs
│ │ └── UI/
│ │ ├── CFGWidget.Designer.cs
│ │ ├── CFGWidget.cs
│ │ ├── CFGWidget.resx
│ │ ├── InstructionWidget.Designer.cs
│ │ ├── InstructionWidget.cs
│ │ ├── InstructionWidget.resx
│ │ ├── ParameterWidget.Designer.cs
│ │ ├── ParameterWidget.cs
│ │ ├── ScrutinizerForm.Designer.cs
│ │ ├── ScrutinizerForm.cs
│ │ └── ScrutinizerForm.resx
│ ├── ScrutinizerTypes.cs
│ └── Wrapper/
│ ├── AMDAsic_Impl.cpp
│ ├── AMDAsic_Impl.h
│ ├── AMDDriver_Impl.cpp
│ ├── AMDDriver_Impl.h
│ ├── AMDShader_Impl.cpp
│ ├── AMDShader_Impl.h
│ ├── D3DCompiler_Impl.cpp
│ ├── D3DCompiler_Impl.h
│ ├── DXILCompiler_Impl.cpp
│ ├── DXILCompiler_Impl.h
│ ├── GCN1Decoder.cpp
│ ├── GCN1Decoder.h
│ ├── GCN3Decoder.cpp
│ ├── GCN3Decoder.h
│ ├── GCNBufferedPrinter.h
│ ├── GCNDecoder.cpp
│ ├── GCNDecoder.h
│ ├── GCNDisassembler.cpp
│ ├── GCNDisassembler.h
│ ├── GCNEnums.cpp
│ ├── GCNEnums.h
│ ├── GCNIsa.cpp
│ ├── GCNIsa.h
│ ├── GCNSimulator.cpp
│ ├── GCNSimulator.h
│ ├── GLSLOpt_Impl.cpp
│ ├── GLSLOpt_Impl.h
│ ├── GLSlang_Impl.cpp
│ ├── GLSlang_Impl.h
│ ├── GLSlang_Stubs.cpp
│ ├── Scrutinizer_GCN.cpp
│ ├── Scrutinizer_GCN.h
│ ├── Utilities.h
│ ├── Wrapper.cpp
│ ├── Wrapper.vcxproj
│ ├── Wrapper.vcxproj.filters
│ ├── amd-codexl-analyzer/
│ │ ├── Common/
│ │ │ └── Src/
│ │ │ └── DeviceInfo/
│ │ │ ├── DeviceInfo.h
│ │ │ ├── DeviceInfoUtils.cpp
│ │ │ └── DeviceInfoUtils.h
│ │ └── CommonProjects/
│ │ └── AMDTBackend/
│ │ └── Include/
│ │ └── Common/
│ │ ├── AmdDxGsaCompile.h
│ │ └── asic_reg/
│ │ ├── atiid.h
│ │ ├── ci_id.h
│ │ ├── cz_id.h
│ │ ├── evergreen_id.h
│ │ ├── kv_id.h
│ │ ├── northernisland_id.h
│ │ ├── si_id.h
│ │ ├── sumo_id.h
│ │ ├── tn_id.h
│ │ └── vi_id.h
│ ├── dxc/
│ │ ├── HLSL/
│ │ │ ├── DXIL.h
│ │ │ ├── DxilCBuffer.h
│ │ │ ├── DxilCompType.h
│ │ │ ├── DxilConstants.h
│ │ │ ├── DxilContainer.h
│ │ │ ├── DxilGenerationPass.h
│ │ │ ├── DxilInstructions.h
│ │ │ ├── DxilInterpolationMode.h
│ │ │ ├── DxilMetadataHelper.h
│ │ │ ├── DxilModule.h
│ │ │ ├── DxilOperations.h
│ │ │ ├── DxilPipelineStateValidation.h
│ │ │ ├── DxilResource.h
│ │ │ ├── DxilResourceBase.h
│ │ │ ├── DxilRootSignature.h
│ │ │ ├── DxilSampler.h
│ │ │ ├── DxilSemantic.h
│ │ │ ├── DxilShaderModel.h
│ │ │ ├── DxilSigPoint.h
│ │ │ ├── DxilSignature.h
│ │ │ ├── DxilSignatureAllocator.h
│ │ │ ├── DxilSignatureElement.h
│ │ │ ├── DxilSpanAllocator.h
│ │ │ ├── DxilTypeSystem.h
│ │ │ ├── DxilValidation.h
│ │ │ ├── HLMatrixLowerHelper.h
│ │ │ ├── HLMatrixLowerPass.h
│ │ │ ├── HLModule.h
│ │ │ ├── HLOperationLower.h
│ │ │ ├── HLOperationLowerExtension.h
│ │ │ ├── HLOperations.h
│ │ │ ├── HLResource.h
│ │ │ ├── HLSLExtensionsCodegenHelper.h
│ │ │ └── ReducibilityAnalysis.h
│ │ ├── HlslIntrinsicOp.h
│ │ ├── Support/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── DxcLangExtensionsHelper.h
│ │ │ ├── ErrorCodes.h
│ │ │ ├── FileIOHelper.h
│ │ │ ├── Global.h
│ │ │ ├── HLSLOptions.h
│ │ │ ├── HLSLOptions.td
│ │ │ ├── Unicode.h
│ │ │ ├── WinIncludes.h
│ │ │ ├── dxcapi.impl.h
│ │ │ ├── dxcapi.use.h
│ │ │ ├── exception.h
│ │ │ └── microcom.h
│ │ ├── Tracing/
│ │ │ ├── CMakeLists.txt
│ │ │ └── dxcetw.man
│ │ ├── dxcapi.h
│ │ ├── dxcapi.internal.h
│ │ ├── dxcisense.h
│ │ └── dxctools.h
│ └── elf.h
└── test/
├── ShadowMaps.txt
├── branches_test
├── cs_addreturntest
├── cs_append
├── cs_barrier_test
├── cs_cull
├── cs_raster.hlsl
├── cs_raycaster
├── cs_sepgauss
├── include/
│ ├── include_d.txt
│ └── include_e.txt
├── include_a.txt
├── include_b.txt
├── include_root.txt
├── manual_trilerp
├── manual_trilerp_glsl
├── matthias_bug
├── mips
├── moblur_reduc
├── ps_lighting.txt
├── ps_lighting_normalmap
├── ps_ubershader
├── trivial_test_shaders.txt
├── trivial_vs_glsl
├── vs_rigid
└── vs_skinning
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
bin/* binary
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
src/.vs/*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
# Roslyn cache directories
*.ide/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
#NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# If using the old MSBuild-Integrated Package Restore, uncomment this:
#!**/packages/repositories.config
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Windows
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
================================================
FILE: .gitmodules
================================================
[submodule "src/Wrapper/glsl-optimizer"]
path = src/Wrapper/glsl-optimizer
url = https://github.com/jbarczak/glsl-optimizer
[submodule "src/Wrapper/GLSlang"]
path = src/Wrapper/GLSlang
url = https://github.com/jbarczak/GLSlang
================================================
FILE: Distribute.bat
================================================
echo off
mkdir Pyramid
mkdir Pyramid\bin
mkdir Pyramid\src
mkdir Pyramid\src\Backends
mkdir Pyramid\src\Languages
mkdir Pyramid\src\MainUI
mkdir Pyramid\src\Properties
mkdir Pyramid\src\Wrapper
mkdir Pyramid\src\Wrapper\glsl-optimizer
mkdir Pyramid\src\Wrapper\GLSlang
cp -r bin/* Pyramid/bin
cp -r LICENSE.txt Pyramid/LICENSE.txt
cp -r README.txt Pyramid/README.txt
cp src/*.cs Pyramid/src
cp src/*.resx Pyramid/src
cp src/Backends/*.cs Pyramid/src/Backends
cp src/Backends/*.resx Pyramid/src/Backends
cp src/Languages/*.cs Pyramid/src/Languages
cp src/Languages/*.resx Pyramid/src/Languages
cp src/MainUI/*.cs Pyramid/src/MainUI
cp src/MainUI/*.resx Pyramid/src/MainUI
cp src/App.config Pyramid/src/App.config
cp src/*.csproj Pyramid/src
cp src/Pyramid.sln Pyramid/src/Pyramid.sln
cp -r src/Properties/* Pyramid/src/Properties
cp src/Wrapper/*.cpp Pyramid/src/Wrapper
cp src/Wrapper/*.h Pyramid/src/Wrapper
cp src/Wrapper/Wrapper.vcxproj Pyramid/src/Wrapper
cp src/Wrapper/Wrapper.vcxproj.filters Pyramid/src/Wrapper
cp -r src/Wrapper/glsl-optimizer Pyramid/src/Wrapper
cp src/Wrapper/GLSlang/glslang_vs2013.vcxproj Pyramid/src/Wrapper/GLSlang/glslang_vs2013.vcxproj
cp -r src/Wrapper/GLSlang/glslang Pyramid/src/Wrapper/GLSlang
cp -r src/Wrapper/GLSlang/OGLCompilersDLL Pyramid/src/Wrapper/GLSlang
cp -r src/Wrapper/GLSlang/tools Pyramid/src/Wrapper/GLSlang
================================================
FILE: LICENSE.txt
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: README.md
================================================
# Pyramid
Pyramid is a free, open GUI tool for offline shader validation and analysis. The UI takes HLSL or GLSL as input, and runs them through various shader
compilers and static analyzers.
Here is Pyramid, showing HLSL shader compiled and disassembled for AMD's GCN, and a GLSL shader compiled and disassembled for PowerVR 6 *(click for full-size image)*:
[](doc/ui-hlsl-amddxx.png?raw=1)
[](doc/ui-glsl-powervr.png?raw=1)
Currently, Pyramid supports these tools:
* HLSL:
* Microsoft D3D compiler *(d3dcompiler_47)*: for showing D3D assembly.
* AMD DXX driver *(Catalyst 14.9)*, used for GCN disassembly and [shader execution simulation](http://www.joshbarczak.com/blog/?p=823).
* AMD [CodeXL analyzer](http://developer.amd.com/tools-and-sdks/opencl-zone/codexl/) *(version 1.5)*.
* glslang HLSL front end (2017 January build)
* [DXC] (https://github.com/microsoft/DirectXShadercompiler)
* [Intel Shader Analyzer](http://github.com/GameTechDev/IntelShaderAnalyzer)
* GLSL:
* Khronos reference [glslang](https://github.com/KhronosGroup/glslang) validator *(2017 January build)*.
* Imagination [PowerVR Rogue compiler](https://community.imgtec.com/developers/powervr/tools/pvrshadereditor/) *(version 3.4)*.
* ARM [Mali offline compiler](http://malideveloper.arm.com/resources/tools/mali-offline-compiler/) *(version 4.6)*.
* [glsl-optimizer](https://github.com/aras-p/glsl-optimizer) *(2015 November build)*.
All the above tools are included under bin/ folder for convenience. These are all publicly available binaries, but I do not own them, maintain them,
and am not responsible for them. If you like you can use the Options screen to point Pyramid at different versions of the tools.
Pyramid is intended to eventually support arbitrary languages and glue together tools and disassemblers from all over
the graphics world.
IHVs: You want developers scrutinizing the ISA for your GPUs. You know you do :) I will work with you to incorporate your disassemblers into this tool. I am willing to jump through hoops to make this happen, just tell me what I need to do.
## Obtaining Pyramid
The best way to obtain a copy is to ask github to download a zip of the repository. The `bin` directory will be updated periodically with an up to date binary.
Pyramid is built against .NET framework 4.5 and runs on Windows. If you don't have it, you need to go get it. Otherwise, just put the contents of `bin` wherever
you like, there is no installer.
Pyramid will create a configuration file under `AppData\Local\Pyramid`. At runtime, it will also create and delete temporary files in this location. Apart from that,
there are no other changes made to the system. In particular, there is no registry nonsense.
Pyramid is distributed as is. There is no warranty of any kind. I will not guarantee timely support, but I will be happy to accept bug fixes, patches, or contributions.
[License](LICENSE.txt) is GPL.
You may send constructive feedback to: jbarcz1@gmail.com
## Building it Yourself
Due to my use of submodules, downloading a zip will not get you the full source.
The best way to obtain the full source is to install git, open a shell, and type:
git clone --recurse https://github.com/jbarczak/Pyramid
This will ensure that all of the submodules are downloaded. github does not include submodules when you download a zip.
I use and recommend MSysGit: https://msysgit.github.io/
Pyramid was developed using VC++ 2013 express edition (Desktop). It runs correctly on my machine (Windows 8.1 with VC++ express installed).
The build products will be copied from `src/bin` into `bin` on each compile.
By default, Pyramid uses relative paths to look for all of the external binaries. For debugging, it's best to point the working directory at `bin` so that they will be found. Alternatively, you can use the options menu to replace the paths with absolutes.
================================================
FILE: shims/atidxx_shim/ShimDLL.cpp
================================================
#define _CRT_SECURE_NO_DEPRECATE
#include
#include
#include
#include
#include "elf.h"
#include
#include "d3d11tokenizedprogramformat.hpp"
struct esi_struct;
struct edi_struct;
#define CALL __cdecl
typedef DWORD (CALL *COMPILE_SHADER)( esi_struct*, edi_struct* );
typedef void (CALL *FREE_SHADER) (void*);
static FILE* g_pLog = 0;
static COMPILE_SHADER g_pCompileShader = 0;
static FREE_SHADER g_pFreeShader = 0;
static HMODULE g_hAMDDriver = 0;
static CRITICAL_SECTION g_Lock;
class ScopedLock
{
public:
ScopedLock() { EnterCriticalSection(&g_Lock); }
~ScopedLock() { LeaveCriticalSection(&g_Lock); }
};
void Log( const char* Format, ... )
{
va_list vl;
va_start(vl,Format);
int n = _vscprintf( Format, vl );
char* p = (char*) malloc( n+1 );
vsprintf(p,Format,vl);
printf(p);
OutputDebugStringA(p);
if( g_pLog )
fprintf( g_pLog, p );
free(p);
va_end(vl);
}
enum
{
INVALID_ARG = 0x80070057,
UNSPECIFIED_ERROR = 0x80004005,
};
struct esi_struct
{
DWORD d0; // esi Two dwords here that get passed into a call (pointer and size)? asic info?
DWORD d1; // esi+4
DWORD* pShaderBlob; // esi+8 If this is zero, return error ... pointer to D3D bytecode?
DWORD nShaderBlobLengthInBytes; // esi+10h. If this is non-zero, go to (53581b4e) (jumps over the esi+14h test)
void * oddball; // esi+14h. If this is non-zero, error, but only if esi+10 is also
DWORD mystery0;
void Print( )
{
Log( "esi_struct at: 0x%08x { 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x }\n",
this, d0,d1,pShaderBlob,nShaderBlobLengthInBytes,
oddball, mystery0 );
}
};
struct edi_struct
{
DWORD size; // 12
Elf32_Ehdr* pHeader;
DWORD nDataSize;
void Print( )
{
Log("edi_struct at (0x%08x): { 0x%08x 0x%08x 0x%08x }\n", this, size, pHeader,nDataSize );
}
void PrintSections( )
{
char* pHeaderBytes = (char*)pHeader;
Elf32_Shdr* pSections = (Elf32_Shdr*) (pHeaderBytes + pHeader->e_shoff);
Elf32_Shdr* pStringTable = pSections + pHeader->e_shstrndx;
char* pElfStringTable = pHeaderBytes + pStringTable->sh_offset;
for( DWORD i=0; ie_shnum; i++ )
{
DWORD nString = pSections[i].sh_name;
char* p = pElfStringTable + pSections[i].sh_name;
char* pSectionData = pHeaderBytes + pSections[i].sh_offset;
Log("ELF Section: %u named: %s (%u bytes)\n", i, p, pSections[i].sh_size );
}
}
void PrintGoryDetails( )
{
char* pHeaderBytes = (char*)pHeader;
Elf32_Shdr* pSections = (Elf32_Shdr*) (pHeaderBytes + pHeader->e_shoff);
Elf32_Shdr* pStringTable = pSections + pHeader->e_shstrndx;
char* pElfStringTable = pHeaderBytes + pStringTable->sh_offset;
for( DWORD i=0; ie_shnum; i++ )
{
DWORD nString = pSections[i].sh_name;
char* p = pElfStringTable + pSections[i].sh_name;
char* pSectionData = pHeaderBytes + pSections[i].sh_offset;
Log("ELF Section: %u named: %s (%u bytes)\n", i, p, pSections[i].sh_size );
Log("********************\n");
if( pSections[i].sh_size % 4 == 0 )
{
for( DWORD k=0; kd0, esi->d1);
h = g_pCompileShader(esi,edi);
return h;
}
__declspec(dllexport) void CALL AmdDxGsaFreeCompiledShader( void* p )
{
ScopedLock l;
if( g_pFreeShader )
g_pFreeShader(p);
}
}
BOOL WINAPI DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD fdwReason,
_In_ LPVOID lpvReserved
)
{
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
{
InitializeCriticalSection(&g_Lock);
g_pLog = fopen("ShimLog.txt", "a" );
if( !g_pLog )
Log("Failed to open log\n");
HMODULE hAMDDriver = LoadLibrary( "real_driver.dll" );
if( !hAMDDriver )
return UNSPECIFIED_ERROR;
FARPROC pCompile = GetProcAddress( hAMDDriver, "AmdDxGsaCompileShader" );
FARPROC pFree = GetProcAddress( hAMDDriver, "AmdDxGsaFreeCompiledShader" );
if( !pCompile || !pFree )
{
FreeLibrary(hAMDDriver);
return FALSE;
}
g_pCompileShader = (COMPILE_SHADER) pCompile;
g_pFreeShader = (FREE_SHADER) pFree;
Log("**************************************************************************\n");
Log("Pyramid driver shim has loaded\n");
Log("Command line: %s\n", GetCommandLineA() );
}
break;
case DLL_PROCESS_DETACH:
DeleteCriticalSection( &g_Lock );
if( g_hAMDDriver )
{
FreeLibrary(g_hAMDDriver);
g_pFreeShader=0;
g_pCompileShader=0;
g_hAMDDriver=0;
Log("Pyramid driver shim has unloaded\n");
}
if( g_pLog )
{
fclose(g_pLog);
g_pLog=0;
}
break;
}
return TRUE;
}
================================================
FILE: shims/atidxx_shim/ShimDLL.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShimDLL", "ShimDLL.vcxproj", "{FCD07E16-50F2-49AF-BF11-F50A9FBAA5AC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FCD07E16-50F2-49AF-BF11-F50A9FBAA5AC}.Debug|Win32.ActiveCfg = Debug|Win32
{FCD07E16-50F2-49AF-BF11-F50A9FBAA5AC}.Debug|Win32.Build.0 = Debug|Win32
{FCD07E16-50F2-49AF-BF11-F50A9FBAA5AC}.Release|Win32.ActiveCfg = Release|Win32
{FCD07E16-50F2-49AF-BF11-F50A9FBAA5AC}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
================================================
FILE: shims/atidxx_shim/ShimDLL.vcxproj
================================================
DebugWin32ReleaseWin32{FCD07E16-50F2-49AF-BF11-F50A9FBAA5AC}ShimDLLDynamicLibrarytruev120NotSetDynamicLibraryfalsev120trueNotSetatidxx32C:\Users\jbarczak\Documents\Projects\Blog\reverse_engineering_gsa\binatidxx32Level3DisabledtrueMultiThreadedDebugtrueLevel3MaxSpeedtruetruetrueMultiThreadedtruetruetrue
================================================
FILE: shims/atidxx_shim/elf.h
================================================
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#ifndef _SYS_ELF_H
#define _SYS_ELF_H
#include
/* Type for a 16-bit quantity. */
typedef uint16_t Elf32_Half;
typedef uint16_t Elf64_Half;
/* Types for signed and unsigned 32-bit quantities. */
typedef uint32_t Elf32_Word;
typedef int32_t Elf32_Sword;
typedef uint32_t Elf64_Word;
typedef int32_t Elf64_Sword;
/* Types for signed and unsigned 64-bit quantities. */
typedef uint64_t Elf32_Xword;
typedef int64_t Elf32_Sxword;
typedef uint64_t Elf64_Xword;
typedef int64_t Elf64_Sxword;
/* Type of addresses. */
typedef uint32_t Elf32_Addr;
typedef uint64_t Elf64_Addr;
/* Type of file offsets. */
typedef uint32_t Elf32_Off;
typedef uint64_t Elf64_Off;
#ifdef __cplusplus
extern "C" {
#endif
#define ELF32_FSZ_ADDR 4
#define ELF32_FSZ_HALF 2
#define ELF32_FSZ_OFF 4
#define ELF32_FSZ_SWORD 4
#define ELF32_FSZ_WORD 4
#define ELF64_FSZ_ADDR 8
#define ELF64_FSZ_HALF 2
#define ELF64_FSZ_OFF 8
#define ELF64_FSZ_SWORD 4
#define ELF64_FSZ_WORD 4
#define ELF64_FSZ_SXWORD 8
#define ELF64_FSZ_XWORD 8
/*
* "Enumerations" below use ...NUM as the number of
* values in the list. It should be 1 greater than the
* highest "real" value.
*/
/*
* ELF header
*/
#define EI_NIDENT 16
typedef struct {
unsigned char e_ident[EI_NIDENT]; /* ident bytes */
Elf32_Half e_type; /* file type */
Elf32_Half e_machine; /* target machine */
Elf32_Word e_version; /* file version */
Elf32_Addr e_entry; /* start address */
Elf32_Off e_phoff; /* phdr file offset */
Elf32_Off e_shoff; /* shdr file offset */
Elf32_Word e_flags; /* file flags */
Elf32_Half e_ehsize; /* sizeof ehdr */
Elf32_Half e_phentsize; /* sizeof phdr */
Elf32_Half e_phnum; /* number phdrs */
Elf32_Half e_shentsize; /* sizeof shdr */
Elf32_Half e_shnum; /* number shdrs */
Elf32_Half e_shstrndx; /* shdr string index */
} Elf32_Ehdr;
#define EI_MAG0 0 /* e_ident[] indexes */
#define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4 /* File class */
#define EI_DATA 5 /* Data encoding */
#define EI_VERSION 6 /* File version */
#define EI_OSABI 7 /* Operating system/ABI identification */
#define EI_ABIVERSION 8 /* ABI version */
#define EI_PAD 9 /* Start of padding bytes */
#define ELFMAG0 0x7f /* EI_MAG */
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFMAG "\177ELF"
#define SELFMAG 4
#define ELFCLASSNONE 0 /* EI_CLASS */
#define ELFCLASS32 1
#define ELFCLASS64 2
#define ELFCLASSNUM 3
#define ELFDATANONE 0 /* EI_DATA */
#define ELFDATA2LSB 1
#define ELFDATA2MSB 2
#define ELFDATANUM 3
#define ET_NONE 0 /* e_type */
#define ET_REL 1
#define ET_EXEC 2
#define ET_DYN 3
#define ET_CORE 4
#define ET_NUM 5
#define ET_LOOS 0xfe00 /* OS specific range */
#define ET_LOSUNW 0xfeff
#define ET_SUNWPSEUDO 0xfeff
#define ET_HISUNW 0xfeff
#define ET_HIOS 0xfeff
#define ET_LOPROC 0xff00 /* processor specific range */
#define ET_HIPROC 0xffff
#define ET_LOPROC 0xff00 /* processor specific range */
#define ET_HIPROC 0xffff
#define EM_NONE 0 /* e_machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* Sun SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola 68000 */
#define EM_88K 5 /* Motorola 88000 */
#define EM_486 6 /* Intel 80486 */
#define EM_860 7 /* Intel i860 */
#define EM_MIPS 8 /* MIPS RS3000 Big-Endian */
#define EM_S370 9 /* IBM System/370 Processor */
#define EM_MIPS_RS3_LE 10 /* MIPS RS3000 Little-Endian */
#define EM_RS6000 11 /* RS6000 */
#define EM_UNKNOWN12 12
#define EM_UNKNOWN13 13
#define EM_UNKNOWN14 14
#define EM_PA_RISC 15 /* PA-RISC */
#define EM_PARISC EM_PA_RISC /* Alias: GNU compatibility */
#define EM_nCUBE 16 /* nCUBE */
#define EM_VPP500 17 /* Fujitsu VPP500 */
#define EM_SPARC32PLUS 18 /* Sun SPARC 32+ */
#define EM_960 19 /* Intel 80960 */
#define EM_PPC 20 /* PowerPC */
#define EM_PPC64 21 /* 64-bit PowerPC */
#define EM_S390 22 /* IBM System/390 Processor */
#define EM_UNKNOWN22 EM_S390 /* Alias: Older published name */
#define EM_UNKNOWN23 23
#define EM_UNKNOWN24 24
#define EM_UNKNOWN25 25
#define EM_UNKNOWN26 26
#define EM_UNKNOWN27 27
#define EM_UNKNOWN28 28
#define EM_UNKNOWN29 29
#define EM_UNKNOWN30 30
#define EM_UNKNOWN31 31
#define EM_UNKNOWN32 32
#define EM_UNKNOWN33 33
#define EM_UNKNOWN34 34
#define EM_UNKNOWN35 35
#define EM_V800 36 /* NEX V800 */
#define EM_FR20 37 /* Fujitsu FR20 */
#define EM_RH32 38 /* TRW RH-32 */
#define EM_RCE 39 /* Motorola RCE */
#define EM_ARM 40 /* Advanced RISC Marchines ARM */
#define EM_ALPHA 41 /* Digital Alpha */
#define EM_SH 42 /* Hitachi SH */
#define EM_SPARCV9 43 /* Sun SPARC V9 (64-bit) */
#define EM_TRICORE 44 /* Siemens Tricore embedded processor */
#define EM_ARC 45 /* Argonaut RISC Core, */
/* Argonaut Technologies Inc. */
#define EM_H8_300 46 /* Hitachi H8/300 */
#define EM_H8_300H 47 /* Hitachi H8/300H */
#define EM_H8S 48 /* Hitachi H8S */
#define EM_H8_500 49 /* Hitachi H8/500 */
#define EM_IA_64 50 /* Intel IA64 */
#define EM_MIPS_X 51 /* Stanford MIPS-X */
#define EM_COLDFIRE 52 /* Motorola ColdFire */
#define EM_68HC12 53 /* Motorola M68HC12 */
#define EM_MMA 54 /* Fujitsu MMA Mulimedia Accelerator */
#define EM_PCP 55 /* Siemens PCP */
#define EM_NCPU 56 /* Sony nCPU embedded RISC processor */
#define EM_NDR1 57 /* Denso NDR1 microprocessor */
#define EM_STARCORE 58 /* Motorola Star*Core processor */
#define EM_ME16 59 /* Toyota ME16 processor */
#define EM_ST100 60 /* STMicroelectronics ST100 processor */
#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ */
/* embedded processor family */
#define EM_AMD64 62 /* AMDs x86-64 architecture */
#define EM_X86_64 EM_AMD64 /* (compatibility) */
#define EM_PDSP 63 /* Sony DSP Processor */
#define EM_UNKNOWN64 64
#define EM_UNKNOWN65 65
#define EM_FX66 66 /* Siemens FX66 microcontroller */
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+8/16 bit */
/* microcontroller */
#define EM_ST7 68 /* STMicroelectronics ST7 8-bit */
/* microcontroller */
#define EM_68HC16 69 /* Motorola MC68HC16 Microcontroller */
#define EM_68HC11 70 /* Motorola MC68HC11 Microcontroller */
#define EM_68HC08 71 /* Motorola MC68HC08 Microcontroller */
#define EM_68HC05 72 /* Motorola MC68HC05 Microcontroller */
#define EM_SVX 73 /* Silicon Graphics SVx */
#define EM_ST19 74 /* STMicroelectronics ST19 8-bit */
/* microcontroller */
#define EM_VAX 75 /* Digital VAX */
#define EM_CRIS 76 /* Axis Communications 32-bit */
/* embedded processor */
#define EM_JAVELIN 77 /* Infineon Technologies 32-bit */
/* embedded processor */
#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
#define EM_MMIX 80 /* Donald Knuth's educational */
/* 64-bit processor */
#define EM_HUANY 81 /* Harvard University */
/* machine-independent */
/* object files */
#define EM_PRISM 82 /* SiTera Prism */
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
#define EM_FR30 84 /* Fujitsu FR30 */
#define EM_D10V 85 /* Mitsubishi D10V */
#define EM_D30V 86 /* Mitsubishi D30V */
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Mitsubishi M32R */
#define EM_MN10300 89 /* Matsushita MN10300 */
#define EM_MN10200 90 /* Matsushita MN10200 */
#define EM_PJ 91 /* picoJava */
#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
#define EM_XTENSA 94 /* Tensilica Xtensa architecture */
#define EM_NUM 95
#define EV_NONE 0 /* e_version, EI_VERSION */
#define EV_CURRENT 1
#define EV_NUM 2
#define ELFOSABI_NONE 0 /* No extensions or unspecified */
#define ELFOSABI_SYSV ELFOSABI_NONE
#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */
#define ELFOSABI_NETBSD 2 /* NetBSD */
#define ELFOSABI_LINUX 3 /* Linux */
#define ELFOSABI_UNKNOWN4 4
#define ELFOSABI_UNKNOWN5 5
#define ELFOSABI_SOLARIS 6 /* Sun Solaris */
#define ELFOSABI_AIX 7 /* AIX */
#define ELFOSABI_IRIX 8 /* IRIX */
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
#define ELFOSABI_OPENBSD 12 /* Open BSD */
#define ELFOSABI_OPENVMS 13 /* Open VMS */
#define ELFOSABI_NSK 14 /* Hewlett-Packard Non-Stop Kernel */
#define ELFOSABI_AROS 15 /* Amiga Research OS */
#define ELFOSABI_ARM 97 /* ARM */
#define ELFOSABI_STANDALONE 255 /* standalone (embedded) application */
/*
* Program header
*/
typedef struct {
Elf32_Word p_type; /* entry type */
Elf32_Off p_offset; /* file offset */
Elf32_Addr p_vaddr; /* virtual address */
Elf32_Addr p_paddr; /* physical address */
Elf32_Word p_filesz; /* file size */
Elf32_Word p_memsz; /* memory size */
Elf32_Word p_flags; /* entry flags */
Elf32_Word p_align; /* memory/file alignment */
} Elf32_Phdr;
#if defined(_LP64) || defined(_LONGLONG_TYPE)
typedef struct {
Elf64_Word p_type; /* entry type */
Elf64_Word p_flags; /* entry flags */
Elf64_Off p_offset; /* file offset */
Elf64_Addr p_vaddr; /* virtual address */
Elf64_Addr p_paddr; /* physical address */
Elf64_Xword p_filesz; /* file size */
Elf64_Xword p_memsz; /* memory size */
Elf64_Xword p_align; /* memory/file alignment */
} Elf64_Phdr;
#endif /* defined(_LP64) || defined(_LONGLONG_TYPE) */
#define PT_NULL 0 /* p_type */
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_TLS 7
#define PT_NUM 8
#define PT_LOOS 0x60000000 /* OS specific range */
/*
* Note: The amd64 psABI defines that the UNWIND program header
* should reside in the OS specific range of the program
* headers.
*/
#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */
#define PT_GNU_EH_FRAME PT_SUNW_UNWIND
#define PT_LOSUNW 0x6ffffffa
#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */
#define PT_SUNWDTRACE 0x6ffffffc /* private */
#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */
#define PT_HISUNW 0x6fffffff
#define PT_HIOS 0x6fffffff
#define PT_LOPROC 0x70000000 /* processor specific range */
#define PT_HIPROC 0x7fffffff
#define PF_R 0x4 /* p_flags */
#define PF_W 0x2
#define PF_X 0x1
#define PF_MASKOS 0x0ff00000 /* OS specific values */
#define PF_MASKPROC 0xf0000000 /* processor specific values */
#define PF_SUNW_FAILURE 0x00100000 /* mapping absent due to failure */
#define PN_XNUM 0xffff /* extended program header index */
/*
* Section header
*/
typedef struct {
Elf32_Word sh_name; /* section name */
Elf32_Word sh_type; /* SHT_... */
Elf32_Word sh_flags; /* SHF_... */
Elf32_Addr sh_addr; /* virtual address */
Elf32_Off sh_offset; /* file offset */
Elf32_Word sh_size; /* section size */
Elf32_Word sh_link; /* misc info */
Elf32_Word sh_info; /* misc info */
Elf32_Word sh_addralign; /* memory alignment */
Elf32_Word sh_entsize; /* entry size if table */
} Elf32_Shdr;
#if defined(_LP64) || defined(_LONGLONG_TYPE)
typedef struct {
Elf64_Word sh_name; /* section name */
Elf64_Word sh_type; /* SHT_... */
Elf64_Xword sh_flags; /* SHF_... */
Elf64_Addr sh_addr; /* virtual address */
Elf64_Off sh_offset; /* file offset */
Elf64_Xword sh_size; /* section size */
Elf64_Word sh_link; /* misc info */
Elf64_Word sh_info; /* misc info */
Elf64_Xword sh_addralign; /* memory alignment */
Elf64_Xword sh_entsize; /* entry size if table */
} Elf64_Shdr;
#endif /* defined(_LP64) || defined(_LONGLONG_TYPE) */
#define SHT_NULL 0 /* sh_type */
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_UNKNOWN12 12
#define SHT_UNKNOWN13 13
#define SHT_INIT_ARRAY 14
#define SHT_FINI_ARRAY 15
#define SHT_PREINIT_ARRAY 16
#define SHT_GROUP 17
#define SHT_SYMTAB_SHNDX 18
#define SHT_NUM 19
/* Solaris ABI specific values */
#define SHT_LOOS 0x60000000 /* OS specific range */
#define SHT_LOSUNW 0x6ffffff1
#define SHT_SUNW_symsort 0x6ffffff1
#define SHT_SUNW_tlssort 0x6ffffff2
#define SHT_SUNW_LDYNSYM 0x6ffffff3
#define SHT_SUNW_dof 0x6ffffff4
#define SHT_SUNW_cap 0x6ffffff5
#define SHT_SUNW_SIGNATURE 0x6ffffff6
#define SHT_SUNW_ANNOTATE 0x6ffffff7
#define SHT_SUNW_DEBUGSTR 0x6ffffff8
#define SHT_SUNW_DEBUG 0x6ffffff9
#define SHT_SUNW_move 0x6ffffffa
#define SHT_SUNW_COMDAT 0x6ffffffb
#define SHT_SUNW_syminfo 0x6ffffffc
#define SHT_SUNW_verdef 0x6ffffffd
#define SHT_SUNW_verneed 0x6ffffffe
#define SHT_SUNW_versym 0x6fffffff
#define SHT_HISUNW 0x6fffffff
#define SHT_HIOS 0x6fffffff
/* GNU/Linux ABI specific values */
#define SHT_GNU_verdef 0x6ffffffd
#define SHT_GNU_verneed 0x6ffffffe
#define SHT_GNU_versym 0x6fffffff
#define SHT_LOPROC 0x70000000 /* processor specific range */
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff
#define SHF_WRITE 0x01 /* sh_flags */
#define SHF_ALLOC 0x02
#define SHF_EXECINSTR 0x04
#define SHF_MERGE 0x10
#define SHF_STRINGS 0x20
#define SHF_INFO_LINK 0x40
#define SHF_LINK_ORDER 0x80
#define SHF_OS_NONCONFORMING 0x100
#define SHF_GROUP 0x200
#define SHF_TLS 0x400
#define SHF_MASKOS 0x0ff00000 /* OS specific values */
#define SHF_MASKPROC 0xf0000000 /* processor specific values */
#define SHN_UNDEF 0 /* special section numbers */
#define SHN_LORESERVE 0xff00
#define SHN_LOPROC 0xff00 /* processor specific range */
#define SHN_HIPROC 0xff1f
#define SHN_LOOS 0xff20 /* OS specific range */
#define SHN_LOSUNW 0xff3f
#define SHN_SUNW_IGNORE 0xff3f
#define SHN_HISUNW 0xff3f
#define SHN_HIOS 0xff3f
#define SHN_ABS 0xfff1
#define SHN_COMMON 0xfff2
#if defined(__APPLE__)
#define SHN_MACHO_64 0xfffd /* Mach-o_64 direct string access */
#define SHN_MACHO 0xfffe /* Mach-o direct string access */
#endif /* __APPLE__ */
#define SHN_XINDEX 0xffff /* extended sect index */
#define SHN_HIRESERVE 0xffff
/*
* Symbol table
*/
typedef struct {
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
unsigned char st_info; /* bind, type: ELF_32_ST_... */
unsigned char st_other;
Elf32_Half st_shndx; /* SHN_... */
} Elf32_Sym;
#if defined(_LP64) || defined(_LONGLONG_TYPE)
typedef struct {
#if !defined(__APPLE__)
Elf64_Word st_name;
#else
Elf64_Sxword st_name;
#endif /* __APPLE__ */
unsigned char st_info; /* bind, type: ELF_64_ST_... */
unsigned char st_other;
Elf64_Half st_shndx; /* SHN_... */
Elf64_Addr st_value;
Elf64_Xword st_size;
} Elf64_Sym;
#endif /* defined(_LP64) || defined(_LONGLONG_TYPE) */
#define STN_UNDEF 0
/*
* The macros compose and decompose values for S.st_info
*
* bind = ELF32_ST_BIND(S.st_info)
* type = ELF32_ST_TYPE(S.st_info)
* S.st_info = ELF32_ST_INFO(bind, type)
*/
#define ELF32_ST_BIND(info) ((info) >> 4)
#define ELF32_ST_TYPE(info) ((info) & 0xf)
#define ELF32_ST_INFO(bind, type) (((bind)<<4)+((type)&0xf))
#define ELF64_ST_BIND(info) ((info) >> 4)
#define ELF64_ST_TYPE(info) ((info) & 0xf)
#define ELF64_ST_INFO(bind, type) (((bind)<<4)+((type)&0xf))
#define STB_LOCAL 0 /* BIND */
#define STB_GLOBAL 1
#define STB_WEAK 2
#define STB_NUM 3
#define STB_LOPROC 13 /* processor specific range */
#define STB_HIPROC 15
#define STT_NOTYPE 0 /* TYPE */
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
#define STT_COMMON 5
#define STT_TLS 6
#define STT_NUM 7
#define STT_LOPROC 13 /* processor specific range */
#define STT_HIPROC 15
/*
* The macros decompose values for S.st_other
*
* visibility = ELF32_ST_VISIBILITY(S.st_other)
*/
#define ELF32_ST_VISIBILITY(other) ((other)&0x7)
#define ELF64_ST_VISIBILITY(other) ((other)&0x7)
#define STV_DEFAULT 0
#define STV_INTERNAL 1
#define STV_HIDDEN 2
#define STV_PROTECTED 3
#define STV_EXPORTED 4
#define STV_SINGLETON 5
#define STV_ELIMINATE 6
#define STV_NUM 7
/*
* Relocation
*/
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info; /* sym, type: ELF32_R_... */
} Elf32_Rel;
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info; /* sym, type: ELF32_R_... */
Elf32_Sword r_addend;
} Elf32_Rela;
#if defined(_LP64) || defined(_LONGLONG_TYPE)
typedef struct {
Elf64_Addr r_offset;
Elf64_Xword r_info; /* sym, type: ELF64_R_... */
} Elf64_Rel;
typedef struct {
Elf64_Addr r_offset;
Elf64_Xword r_info; /* sym, type: ELF64_R_... */
Elf64_Sxword r_addend;
} Elf64_Rela;
#endif /* defined(_LP64) || defined(_LONGLONG_TYPE) */
/*
* The macros compose and decompose values for Rel.r_info, Rela.f_info
*
* sym = ELF32_R_SYM(R.r_info)
* type = ELF32_R_TYPE(R.r_info)
* R.r_info = ELF32_R_INFO(sym, type)
*/
#define ELF32_R_SYM(info) ((info)>>8)
#define ELF32_R_TYPE(info) ((unsigned char)(info))
#define ELF32_R_INFO(sym, type) (((sym)<<8)+(unsigned char)(type))
#define ELF64_R_SYM(info) ((info)>>32)
#define ELF64_R_TYPE(info) ((Elf64_Word)(info))
#define ELF64_R_INFO(sym, type) (((Elf64_Xword)(sym)<<32)+(Elf64_Xword)(type))
/*
* The r_info field is composed of two 32-bit components: the symbol
* table index and the relocation type. The relocation type for SPARC V9
* is further decomposed into an 8-bit type identifier and a 24-bit type
* dependent data field. For the existing Elf32 relocation types,
* that data field is zero.
*/
#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40)
#define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56)
#define ELF64_R_TYPE_INFO(data, type) \
(((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type))
/*
* Section Group Flags (SHT_GROUP)
*/
#define GRP_COMDAT 0x01
/*
* Note entry header
*/
typedef struct {
Elf32_Word n_namesz; /* length of note's name */
Elf32_Word n_descsz; /* length of note's "desc" */
Elf32_Word n_type; /* type of note */
} Elf32_Nhdr;
#if defined(_LP64) || defined(_LONGLONG_TYPE)
typedef struct {
Elf64_Word n_namesz; /* length of note's name */
Elf64_Word n_descsz; /* length of note's "desc" */
Elf64_Word n_type; /* type of note */
} Elf64_Nhdr;
#endif /* defined(_LP64) || defined(_LONGLONG_TYPE) */
/*
* Move entry
*/
#if defined(_LP64) || defined(_LONGLONG_TYPE)
typedef struct {
Elf32_Lword m_value; /* symbol value */
Elf32_Word m_info; /* size + index */
Elf32_Word m_poffset; /* symbol offset */
Elf32_Half m_repeat; /* repeat count */
Elf32_Half m_stride; /* stride info */
} Elf32_Move;
/*
* The macros compose and decompose values for Move.r_info
*
* sym = ELF32_M_SYM(M.m_info)
* size = ELF32_M_SIZE(M.m_info)
* M.m_info = ELF32_M_INFO(sym, size)
*/
#define ELF32_M_SYM(info) ((info)>>8)
#define ELF32_M_SIZE(info) ((unsigned char)(info))
#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
typedef struct {
Elf64_Lword m_value; /* symbol value */
Elf64_Xword m_info; /* size + index */
Elf64_Xword m_poffset; /* symbol offset */
Elf64_Half m_repeat; /* repeat count */
Elf64_Half m_stride; /* stride info */
} Elf64_Move;
#define ELF64_M_SYM(info) ((info)>>8)
#define ELF64_M_SIZE(info) ((unsigned char)(info))
#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
#endif /* defined(_LP64) || defined(_LONGLONG_TYPE) */
/*
* Hardware/Software capabilities entry
*/
#ifndef _ASM
typedef struct {
Elf32_Word c_tag; /* how to interpret value */
union {
Elf32_Word c_val;
Elf32_Addr c_ptr;
} c_un;
} Elf32_Cap;
#if defined(_LP64) || defined(_LONGLONG_TYPE)
typedef struct {
Elf64_Xword c_tag; /* how to interpret value */
union {
Elf64_Xword c_val;
Elf64_Addr c_ptr;
} c_un;
} Elf64_Cap;
#endif /* defined(_LP64) || defined(_LONGLONG_TYPE) */
#endif
#define CA_SUNW_NULL 0
#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */
#define CA_SUNW_SF_1 2 /* first software capabilities entry */
/*
* Define software capabilities (CA_SUNW_SF_1 values). Note, hardware
* capabilities (CA_SUNW_HW_1 values) are taken directly from sys/auxv_$MACH.h.
*/
#define SF1_SUNW_FPKNWN 0x001 /* use/non-use of frame pointer is */
#define SF1_SUNW_FPUSED 0x002 /* known, and frame pointer is */
/* in use */
#define SF1_SUNW_MASK 0x003 /* known software capabilities mask */
/*
* Known values for note entry types (e_type == ET_CORE)
*/
#define NT_PRSTATUS 1 /* prstatus_t */
#define NT_PRFPREG 2 /* prfpregset_t */
#define NT_PRPSINFO 3 /* prpsinfo_t */
#define NT_PRXREG 4 /* prxregset_t */
#define NT_PLATFORM 5 /* string from sysinfo(SI_PLATFORM) */
#define NT_AUXV 6 /* auxv_t array */
#define NT_GWINDOWS 7 /* gwindows_t SPARC only */
#define NT_ASRS 8 /* asrset_t SPARC V9 only */
#define NT_LDT 9 /* ssd array IA32 only */
#define NT_PSTATUS 10 /* pstatus_t */
#define NT_PSINFO 13 /* psinfo_t */
#define NT_PRCRED 14 /* prcred_t */
#define NT_UTSNAME 15 /* struct utsname */
#define NT_LWPSTATUS 16 /* lwpstatus_t */
#define NT_LWPSINFO 17 /* lwpsinfo_t */
#define NT_PRPRIV 18 /* prpriv_t */
#define NT_PRPRIVINFO 19 /* priv_impl_info_t */
#define NT_CONTENT 20 /* core_content_t */
#define NT_ZONENAME 21 /* string from getzonenamebyid(3C) */
#define NT_NUM 21
#ifdef _KERNEL
/*
* The following routine checks the processor-specific
* fields of an ELF header.
*/
int elfheadcheck(unsigned char, Elf32_Half, Elf32_Word);
#endif
#ifdef __cplusplus
}
#endif
#if defined(ELF_TARGET_ALL) || defined(ELF_TARGET_SPARC)
#include
#endif
#if defined(ELF_TARGET_ALL) || defined(ELF_TARGET_386)
#if !defined(__APPLE__)
#include
#else /* is Apple Mac OS X */
#include "elf_386.h" /* In lieu of Solaris */
#endif /* __APPLE__ */
#endif
#if defined(ELF_TARGET_ALL) || defined(ELF_TARGET_AMD64)
#include
#endif
#endif /* _SYS_ELF_H */
================================================
FILE: src/App.config
================================================
================================================
FILE: src/Backends/AMDDriverBackend.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Pyramid
{
class AMDDriverResultSet : IResultSet
{
private AMDDriverResultsPanel m_Results;
private TextBox m_Analysis = new TextBox();
public string Name { get { return "AMDDXX"; } }
public Control AnalysisPanel { get { return m_Analysis; } }
public Control ResultsPanel { get { return m_Results; } }
public AMDDriverResultSet( IDXShaderReflection reflection )
{
m_Results = new AMDDriverResultsPanel(reflection);
m_Analysis.Dock = DockStyle.Fill;
m_Analysis.ReadOnly = true;
m_Analysis.Multiline = true;
m_Analysis.Font = new System.Drawing.Font("Lucida Console", 8);
m_Results.AsicChanged += delegate(IAMDShader sh)
{
m_Analysis.Text = sh.PrintStats();
};
}
public void Add( IAMDShader sh )
{
m_Results.AddResult(sh);
}
}
class AMDDriverBackendOptions : IBackendOptions
{
private List m_RequestedAsics;
public AMDDriverBackendOptions(List requestedAsics)
{
m_RequestedAsics = (requestedAsics != null) ? requestedAsics : new List();
}
public List Asics { get { return m_RequestedAsics; } }
}
class AMDDriverBackend : IBackend
{
private List m_SupportedAsics = new List();
private ID3DCompiler m_FXC = null;
private IAMDDriver m_Driver = null;
public string Name { get { return "AMDDXX"; } }
public IEnumerable Asics { get { return m_SupportedAsics; } }
public AMDDriverBackend( IAMDDriver driver, ID3DCompiler fxc )
{
m_FXC = fxc;
m_Driver = driver;
if (m_Driver != null)
{
foreach (IAMDAsic asic in m_Driver.Asics)
{
m_SupportedAsics.Add(asic.Name);
}
}
}
private bool CompileForAsic(List asics, string asic)
{
if (asics == null || asics.Count == 0)
return true;
return asics.Contains(asic);
}
public IResultSet Compile(IShader shaderObj, IBackendOptions options)
{
if ( !(shaderObj is HLSLShader ) )
return null;
HLSLShader shaderHLSL = shaderObj as HLSLShader;
IHLSLOptions hlslOpts = shaderHLSL.CompileOptions;
AMDDriverBackendOptions backendOptions = options as AMDDriverBackendOptions;
string shader = shaderObj.Code;
if (shaderHLSL.WasCompiledWithErrors)
return null;
try
{
// compile here if we must. Recycle existing blob if we can
IDXShaderBlob blob = shaderHLSL.CompiledBlob;
if ( blob == null )
{
if (!shaderHLSL.Compile(m_FXC, null))
return null;
blob = shaderHLSL.CompiledBlob;
}
if (!(blob is IDXBCShaderBlob))
return null;
IDXBCShaderBlob dxcBlob = blob as IDXBCShaderBlob;
IDXShaderReflection reflect = dxcBlob.Reflect();
IDXShaderBlob exe = dxcBlob.GetExecutableBlob();
if (exe == null)
return null;
byte[] bytes = exe.ReadBytes();
AMDDriverResultSet rs = new AMDDriverResultSet(reflect );
foreach (IAMDAsic a in m_Driver.Asics)
{
if (CompileForAsic(backendOptions.Asics, a.Name))
{
IAMDShader sh = m_Driver.CompileDXBlob(a, bytes, reflect);
rs.Add(sh);
}
}
return rs;
}
catch( System.Exception ex )
{
MessageBox.Show(ex.Message);
return null;
}
}
}
}
================================================
FILE: src/Backends/AMDDriverResultsPanel.Designer.cs
================================================
namespace Pyramid
{
partial class AMDDriverResultsPanel
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.txtISA = new System.Windows.Forms.TextBox();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.txtHex = new System.Windows.Forms.TextBox();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.txtEncodings = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.cmbAsic = new System.Windows.Forms.ComboBox();
this.btnScrutinize = new System.Windows.Forms.Button();
this.tabControl1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage3.SuspendLayout();
this.SuspendLayout();
//
// tabControl1
//
this.tabControl1.Alignment = System.Windows.Forms.TabAlignment.Bottom;
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage3);
this.tabControl1.Location = new System.Drawing.Point(3, 38);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(320, 185);
this.tabControl1.TabIndex = 5;
//
// tabPage2
//
this.tabPage2.Controls.Add(this.txtISA);
this.tabPage2.Location = new System.Drawing.Point(4, 4);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(312, 159);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Asm";
this.tabPage2.UseVisualStyleBackColor = true;
//
// txtISA
//
this.txtISA.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtISA.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtISA.Location = new System.Drawing.Point(3, 3);
this.txtISA.Multiline = true;
this.txtISA.Name = "txtISA";
this.txtISA.ReadOnly = true;
this.txtISA.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtISA.Size = new System.Drawing.Size(306, 153);
this.txtISA.TabIndex = 0;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.txtHex);
this.tabPage1.Location = new System.Drawing.Point(4, 4);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(312, 159);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Hex";
this.tabPage1.UseVisualStyleBackColor = true;
//
// txtHex
//
this.txtHex.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtHex.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtHex.Location = new System.Drawing.Point(3, 3);
this.txtHex.Multiline = true;
this.txtHex.Name = "txtHex";
this.txtHex.ReadOnly = true;
this.txtHex.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtHex.Size = new System.Drawing.Size(306, 153);
this.txtHex.TabIndex = 0;
//
// tabPage3
//
this.tabPage3.Controls.Add(this.txtEncodings);
this.tabPage3.Location = new System.Drawing.Point(4, 4);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Padding = new System.Windows.Forms.Padding(3);
this.tabPage3.Size = new System.Drawing.Size(312, 159);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "Encodings";
this.tabPage3.UseVisualStyleBackColor = true;
//
// txtEncodings
//
this.txtEncodings.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtEncodings.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtEncodings.Location = new System.Drawing.Point(3, 3);
this.txtEncodings.Multiline = true;
this.txtEncodings.Name = "txtEncodings";
this.txtEncodings.ReadOnly = true;
this.txtEncodings.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtEncodings.Size = new System.Drawing.Size(306, 153);
this.txtEncodings.TabIndex = 1;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(8, 14);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(27, 13);
this.label1.TabIndex = 4;
this.label1.Text = "Asic";
//
// cmbAsic
//
this.cmbAsic.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.cmbAsic.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbAsic.FormattingEnabled = true;
this.cmbAsic.Location = new System.Drawing.Point(47, 11);
this.cmbAsic.Name = "cmbAsic";
this.cmbAsic.Size = new System.Drawing.Size(199, 21);
this.cmbAsic.TabIndex = 3;
this.cmbAsic.SelectedIndexChanged += new System.EventHandler(this.cmbAsic_SelectedIndexChanged);
//
// btnScrutinize
//
this.btnScrutinize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnScrutinize.Location = new System.Drawing.Point(252, 7);
this.btnScrutinize.Name = "btnScrutinize";
this.btnScrutinize.Size = new System.Drawing.Size(64, 27);
this.btnScrutinize.TabIndex = 7;
this.btnScrutinize.Text = "Scrutinize";
this.btnScrutinize.UseVisualStyleBackColor = true;
this.btnScrutinize.Click += new System.EventHandler(this.btnScrutinize_Click);
//
// AMDDriverResultsPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.btnScrutinize);
this.Controls.Add(this.tabControl1);
this.Controls.Add(this.label1);
this.Controls.Add(this.cmbAsic);
this.Name = "AMDDriverResultsPanel";
this.Size = new System.Drawing.Size(326, 235);
this.tabControl1.ResumeLayout(false);
this.tabPage2.ResumeLayout(false);
this.tabPage2.PerformLayout();
this.tabPage1.ResumeLayout(false);
this.tabPage1.PerformLayout();
this.tabPage3.ResumeLayout(false);
this.tabPage3.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TextBox txtISA;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TextBox txtHex;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ComboBox cmbAsic;
private System.Windows.Forms.TabPage tabPage3;
private System.Windows.Forms.TextBox txtEncodings;
private System.Windows.Forms.Button btnScrutinize;
}
}
================================================
FILE: src/Backends/AMDDriverResultsPanel.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Pyramid
{
public partial class AMDDriverResultsPanel : UserControl
{
private List m_Shaders = new List();
IDXShaderReflection m_DXReflection;
public delegate void AsicChangedDelegate(IAMDShader shader);
public event AsicChangedDelegate AsicChanged;
public AMDDriverResultsPanel( IDXShaderReflection shader )
{
InitializeComponent();
m_DXReflection = shader;
btnScrutinize.Enabled = (shader.GetShaderType() == HLSLShaderType.VERTEX ||
shader.GetShaderType() == HLSLShaderType.PIXEL ||
shader.GetShaderType() == HLSLShaderType.COMPUTE );
}
public void AddResult(IAMDShader shader)
{
m_Shaders.Add(shader);
cmbAsic.Items.Add(shader.Asic.Name);
if (cmbAsic.Items.Count == 1)
cmbAsic.SelectedIndex = 0;
}
private string HexDump( IAMDShader sh )
{
byte[] bytes = sh.ReadISABytes();
int nBytes = bytes.Length;
StringBuilder str = new StringBuilder();
if (nBytes % 4 == 0)
{
for (int i = 0; i < nBytes; i += 4)
{
int n = bytes[i] |
bytes[i + 1] << 8 |
bytes[i + 2] << 16 |
bytes[i + 3] << 24;
str.AppendFormat("{0:X8} ", n);
str.AppendLine();
}
}
else
{
for (int i = 0; i < nBytes; i++)
{
if (i % 8 == 0)
str.AppendLine();
str.AppendFormat("{0:X2} ", bytes[i]);
}
}
str.AppendLine();
return str.ToString();
}
private void cmbAsic_SelectedIndexChanged(object sender, EventArgs e)
{
int i = cmbAsic.SelectedIndex;
if (i >= 0 && i < m_Shaders.Count)
{
txtHex.Text = HexDump(m_Shaders[i]);
txtEncodings.Text = m_Shaders[i].ListEncodings();
txtISA.Text = m_Shaders[i].Disassemble();
}
else
{
txtHex.Text = "";
txtISA.Text = "";
}
AsicChanged(m_Shaders[i]);
}
private void btnScrutinize_Click(object sender, EventArgs e)
{
int i = cmbAsic.SelectedIndex;
if (i >= 0 && i < m_Shaders.Count)
{
IAMDShader sh = m_Shaders[cmbAsic.SelectedIndex];
Scrutinizer.IScrutinizer backend = sh.CreateScrutinizer();
List Ops = backend.BuildProgram();
List Fetch = backend.BuildDXFetchShader(m_DXReflection);
Scrutinizer.UI.ScrutinizerForm f = new Scrutinizer.UI.ScrutinizerForm(Fetch, Ops, backend);
f.ShowDialog();
}
}
}
}
================================================
FILE: src/Backends/AMDDriverResultsPanel.resx
================================================
text/microsoft-resx2.0System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089TrueTrueTrueTrueTrueTrue
================================================
FILE: src/Backends/CodeXLAnalysisPanel.Designer.cs
================================================
namespace Pyramid
{
partial class CodeXLAnalysisPanel
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.listView1 = new System.Windows.Forms.ListView();
this.Key = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.Value = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.SuspendLayout();
//
// listView1
//
this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.Key,
this.Value});
this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.listView1.Location = new System.Drawing.Point(0, 0);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(316, 225);
this.listView1.TabIndex = 0;
this.listView1.UseCompatibleStateImageBehavior = false;
this.listView1.View = System.Windows.Forms.View.Details;
//
// Key
//
this.Key.Text = "Key";
this.Key.Width = 95;
//
// Value
//
this.Value.Text = "Value";
this.Value.Width = 98;
//
// AMDAnalysisPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.listView1);
this.Name = "AMDAnalysisPanel";
this.Size = new System.Drawing.Size(316, 225);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ListView listView1;
private System.Windows.Forms.ColumnHeader Key;
private System.Windows.Forms.ColumnHeader Value;
}
}
================================================
FILE: src/Backends/CodeXLAnalysisPanel.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Pyramid
{
public partial class CodeXLAnalysisPanel : UserControl
{
private Dictionary>> m_DataSet = new Dictionary>>();
public CodeXLAnalysisPanel()
{
InitializeComponent();
}
public void AddResult(string asic, Dictionary vals)
{
List> items = new List>();
items.Add(new KeyValuePair("Asic", asic));
items.AddRange(vals);
m_DataSet.Add(asic, items);
if (m_DataSet.Count == 1)
PopulateListView(items);
}
public void SetAsic(string asic)
{
listView1.Items.Clear();
List> items;
if (m_DataSet.TryGetValue(asic, out items))
PopulateListView(items);
}
private void PopulateListView(List> items)
{
foreach (KeyValuePair p in items)
{
string[] arr = new string[2]; //ahoy!
arr[0] = p.Key;
arr[1] = p.Value;
listView1.Items.Add(new ListViewItem(arr));
}
}
}
}
================================================
FILE: src/Backends/CodeXLAnalysisPanel.resx
================================================
text/microsoft-resx2.0System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
================================================
FILE: src/Backends/CodeXLBackend.cs
================================================
using System.Diagnostics;
using System.Collections.Generic;
using System.IO;
using System;
using System.Windows.Forms;
namespace Pyramid
{
class CodeXLResultSet : IResultSet
{
private AMDResultsPanel m_ResultsPanel ;
private CodeXLAnalysisPanel m_AnalysisPanel;
public CodeXLResultSet()
{
m_ResultsPanel = new AMDResultsPanel();
m_AnalysisPanel = new CodeXLAnalysisPanel();
m_ResultsPanel.AsicChanged +=
delegate(string asic)
{
m_AnalysisPanel.SetAsic(asic);
};
}
public Control ResultsPanel { get { return m_ResultsPanel; } }
public Control AnalysisPanel { get { return m_AnalysisPanel; } }
public string Name { get { return "CodeXL"; } }
public int ResultCount { get { return m_ResultsPanel.ResultCount; } }
public void AddCompileResult( string asic, string il, string isa )
{
m_ResultsPanel.AddResult(asic, il, isa);
}
public void AddAnalysisResult( string asic, Dictionary vals )
{
m_AnalysisPanel.AddResult(asic, vals);
}
public void DisplayAsic(string asic)
{
m_AnalysisPanel.SetAsic(asic);
m_ResultsPanel.SetAsic(asic);
}
}
class CodeXLBackendOptions : IBackendOptions
{
private List m_RequestedAsics;
public CodeXLBackendOptions(List requestedAsics)
{
m_RequestedAsics = (requestedAsics != null) ? requestedAsics : new List();
}
public List Asics { get { return m_RequestedAsics; } }
}
class CodeXLBackend : IBackend
{
private List m_SupportedAsics = new List();
private string m_CodeXL = "";
private string m_D3DCompiler = "";
private string m_TempPath = "";
public string Name { get { return "CodeXL"; } }
public IEnumerable Asics { get { return m_SupportedAsics; } }
public static List GetSupportedAsics( string CodeXLPath, string d3dpath )
{
// try to run CodeXLAnalyzer to get the asic list
// -s "HLSL" --DXLocation s -l"
string CommandLine = string.Format("-s \"HLSL\" --DXLocation {0} -l", d3dpath);
List asics = new List();
ProcessStartInfo pi = new ProcessStartInfo();
pi.RedirectStandardOutput = true;
pi.RedirectStandardInput = true;
pi.RedirectStandardError = true;
pi.CreateNoWindow = true;
pi.Arguments = CommandLine;
pi.FileName = CodeXLPath;
pi.UseShellExecute = false;
try
{
Process p = Process.Start(pi);
p.WaitForExit();
while (!p.StandardOutput.EndOfStream)
{
string s = p.StandardOutput.ReadLine();
asics.Add(s.TrimEnd().TrimStart());
}
// skip whatever text they're emitting, up to 'Devices:'
while (!asics[0].Equals("Devices:"))
asics.RemoveAt(0);
asics.RemoveAt(0); // remove 'Devices'
p.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message, "uh-oh, couldn't get CodeXL asic list", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return asics;
}
public CodeXLBackend( string CodeXLPath, string D3DCompilerPath, string TempPath )
{
m_SupportedAsics = GetSupportedAsics(CodeXLPath, D3DCompilerPath);
m_CodeXL = CodeXLPath;
m_D3DCompiler = D3DCompilerPath;
m_TempPath = TempPath;
}
private bool CompileForAsic( List asics, string asic )
{
if (asics == null || asics.Count == 0)
return true;
return asics.Contains(asic);
}
public IResultSet Compile(IShader shader, IBackendOptions options)
{
if ( !(shader is HLSLShader) || !(options is CodeXLBackendOptions) )
return null;
// TODO: Modify CodeXL backend so that it re-uses blob from
// FXC backend where available. It'd be nice not to have to
// have CodeXL recompile it for us
HLSLShader shaderHLSL = shader as HLSLShader;
IHLSLOptions hlslOpts = shaderHLSL.CompileOptions;
CodeXLBackendOptions backendOptions = options as CodeXLBackendOptions;
string text = shader.Code;
if (shaderHLSL.WasCompiledWithErrors)
return null;
string tmpFile = Path.Combine(m_TempPath, "PYRAMID_amdcodexl");
try
{
StreamWriter stream = File.CreateText(tmpFile);
stream.Write(text);
stream.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message, "uh-oh, couldn't create temp file", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
string isaPath = Path.Combine(m_TempPath, "pyramid.isa");
string analysisPath = Path.Combine(m_TempPath, "analysis");
string CommandLine = "-s \"HLSL\"";
CommandLine = String.Concat( CommandLine, String.Format( " -p {0}",hlslOpts.Target.ToString()) );
CommandLine = String.Concat( CommandLine, String.Format( " -f {0} ",hlslOpts.EntryPoint ));
CommandLine = String.Concat( CommandLine, String.Format( " --DXLocation \"{0}\"",m_D3DCompiler ));
CommandLine = String.Concat( CommandLine, String.Format( " --isa \"{0}\"",isaPath ));
CommandLine = String.Concat( CommandLine, String.Format( " -a \"{0}\"",analysisPath ));
CommandLine = String.Concat( CommandLine, String.Format( " --DXFlags {0} ",hlslOpts.GetD3DCompileFlagBits() ));
CommandLine = String.Concat(CommandLine, tmpFile);
foreach (string asic in m_SupportedAsics)
{
if (CompileForAsic(backendOptions.Asics, asic))
{
CommandLine = String.Concat(CommandLine, " -c ", asic, " ");
}
}
ProcessStartInfo pi = new ProcessStartInfo();
pi.RedirectStandardOutput = true;
pi.RedirectStandardInput = true;
pi.RedirectStandardError = true;
pi.CreateNoWindow = true;
pi.Arguments = CommandLine;
pi.FileName = m_CodeXL;
pi.UseShellExecute = false;
string output;
try
{
int TimeOut = 15000; // TODO: Put in options
Process p = Process.Start(pi);
output = p.StandardOutput.ReadToEnd();
if (p.WaitForExit(TimeOut))
{
MessageBox.Show("CodeXL took more than 15 seconds");
}
p.Close();
File.Delete(tmpFile);
}
catch( Exception e )
{
MessageBox.Show(e.Message, "uh-oh, couldn't run CodeXL", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
// Compile results are emitted in one set of files per asic
string defaultAsic = "";
CodeXLResultSet results = new CodeXLResultSet();
foreach (string asic in m_SupportedAsics)
{
if (!CompileForAsic(backendOptions.Asics, asic))
{
continue;
}
if (defaultAsic == "")
{
defaultAsic = asic;
}
string isaFile = Path.Combine(m_TempPath, String.Format("{0}_pyramid.isa", asic));
try
{
string isa = File.ReadAllText(isaFile);
results.AddCompileResult(asic, "CodeXL doesn't support IL output for HLSL", isa);
File.Delete(isaFile);
}
catch (Exception )
{
// may occur in the event of a compile error.
}
}
// Analysis results are emitted in a big CSV file
try
{
string[] lines = File.ReadAllLines(analysisPath);
File.Delete(analysisPath);
try
{
// first line is column names
string columns = lines[0];
string[] cols = columns.Split(',');
// first column is asic, remaining columns are fields we want to display
for (int i = 1; i < lines.Length; i++)
{
string[] data = lines[i].Split(',');
string asic = data[0];
Dictionary vals = new Dictionary();
for (int j = 1; j < cols.Length; j++)
{
if( !String.IsNullOrEmpty(data[j]) && !String.IsNullOrEmpty(cols[j]))
vals.Add(cols[j], data[j]);
}
results.AddAnalysisResult(asic, vals);
}
}
catch( Exception e )
{
MessageBox.Show(e.Message, "uh-oh. Couldn't parse CodeXL analysis file. Did it change?", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch( Exception )
{
// compile error
}
if (results.ResultCount > 0)
{
results.DisplayAsic(defaultAsic);
return results;
}
else
return null;
}
}
}
================================================
FILE: src/Backends/CodeXLResultsPanel.Designer.cs
================================================
namespace Pyramid
{
partial class AMDResultsPanel
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.cmbAsic = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.txtISA = new System.Windows.Forms.TextBox();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.txtIL = new System.Windows.Forms.TextBox();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.txtLiveReg = new System.Windows.Forms.TextBox();
this.tabPage4 = new System.Windows.Forms.TabPage();
this.txtToolOutput = new System.Windows.Forms.TextBox();
this.tabControl1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage3.SuspendLayout();
this.tabPage4.SuspendLayout();
this.SuspendLayout();
//
// cmbAsic
//
this.cmbAsic.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.cmbAsic.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbAsic.FormattingEnabled = true;
this.cmbAsic.Location = new System.Drawing.Point(55, 8);
this.cmbAsic.Name = "cmbAsic";
this.cmbAsic.Size = new System.Drawing.Size(166, 21);
this.cmbAsic.TabIndex = 0;
this.cmbAsic.SelectedIndexChanged += new System.EventHandler(this.cmbAsic_SelectedIndexChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(16, 11);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(27, 13);
this.label1.TabIndex = 1;
this.label1.Text = "Asic";
//
// tabControl1
//
this.tabControl1.Alignment = System.Windows.Forms.TabAlignment.Bottom;
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage3);
this.tabControl1.Controls.Add(this.tabPage4);
this.tabControl1.Location = new System.Drawing.Point(3, 35);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(232, 186);
this.tabControl1.TabIndex = 2;
//
// tabPage2
//
this.tabPage2.Controls.Add(this.txtISA);
this.tabPage2.Location = new System.Drawing.Point(4, 4);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(224, 160);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "ISA";
this.tabPage2.UseVisualStyleBackColor = true;
//
// txtISA
//
this.txtISA.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtISA.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtISA.Location = new System.Drawing.Point(3, 3);
this.txtISA.Multiline = true;
this.txtISA.Name = "txtISA";
this.txtISA.ReadOnly = true;
this.txtISA.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtISA.Size = new System.Drawing.Size(218, 154);
this.txtISA.TabIndex = 0;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.txtIL);
this.tabPage1.Location = new System.Drawing.Point(4, 4);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(224, 160);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "IL";
this.tabPage1.UseVisualStyleBackColor = true;
//
// txtIL
//
this.txtIL.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtIL.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtIL.Location = new System.Drawing.Point(3, 3);
this.txtIL.Multiline = true;
this.txtIL.Name = "txtIL";
this.txtIL.ReadOnly = true;
this.txtIL.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtIL.Size = new System.Drawing.Size(218, 154);
this.txtIL.TabIndex = 0;
//
// tabPage3
//
this.tabPage3.Controls.Add(this.txtLiveReg);
this.tabPage3.Location = new System.Drawing.Point(4, 4);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Padding = new System.Windows.Forms.Padding(3);
this.tabPage3.Size = new System.Drawing.Size(224, 160);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "LiveReg";
this.tabPage3.UseVisualStyleBackColor = true;
//
// txtLiveReg
//
this.txtLiveReg.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtLiveReg.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtLiveReg.Location = new System.Drawing.Point(3, 3);
this.txtLiveReg.Multiline = true;
this.txtLiveReg.Name = "txtLiveReg";
this.txtLiveReg.ReadOnly = true;
this.txtLiveReg.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtLiveReg.Size = new System.Drawing.Size(218, 154);
this.txtLiveReg.TabIndex = 1;
//
// tabPage4
//
this.tabPage4.Controls.Add(this.txtToolOutput);
this.tabPage4.Location = new System.Drawing.Point(4, 4);
this.tabPage4.Name = "tabPage4";
this.tabPage4.Padding = new System.Windows.Forms.Padding(3);
this.tabPage4.Size = new System.Drawing.Size(224, 160);
this.tabPage4.TabIndex = 3;
this.tabPage4.Text = "Output";
this.tabPage4.UseVisualStyleBackColor = true;
//
// txtToolOutput
//
this.txtToolOutput.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtToolOutput.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtToolOutput.Location = new System.Drawing.Point(3, 3);
this.txtToolOutput.Multiline = true;
this.txtToolOutput.Name = "txtToolOutput";
this.txtToolOutput.ReadOnly = true;
this.txtToolOutput.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtToolOutput.Size = new System.Drawing.Size(218, 154);
this.txtToolOutput.TabIndex = 2;
//
// AMDResultsPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tabControl1);
this.Controls.Add(this.label1);
this.Controls.Add(this.cmbAsic);
this.Name = "AMDResultsPanel";
this.Size = new System.Drawing.Size(238, 236);
this.tabControl1.ResumeLayout(false);
this.tabPage2.ResumeLayout(false);
this.tabPage2.PerformLayout();
this.tabPage1.ResumeLayout(false);
this.tabPage1.PerformLayout();
this.tabPage3.ResumeLayout(false);
this.tabPage3.PerformLayout();
this.tabPage4.ResumeLayout(false);
this.tabPage4.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ComboBox cmbAsic;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TextBox txtIL;
private System.Windows.Forms.TextBox txtISA;
private System.Windows.Forms.TabPage tabPage3;
private System.Windows.Forms.TextBox txtLiveReg;
private System.Windows.Forms.TabPage tabPage4;
private System.Windows.Forms.TextBox txtToolOutput;
}
}
================================================
FILE: src/Backends/CodeXLResultsPanel.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace Pyramid
{
public partial class AMDResultsPanel : UserControl
{
private List m_IL = new List();
private List m_ISA = new List();
private List m_LiveReg = new List();
public AMDResultsPanel()
{
InitializeComponent();
}
public int ResultCount { get { return m_IL.Count; } }
public delegate void AsicChangedDelegate( string asic );
public event AsicChangedDelegate AsicChanged;
public void SetToolOutput( string output )
{
txtToolOutput.Text = output;
}
public void AddResult(string Asic, string IL, string ISA)
{
m_IL.Add(IL);
m_ISA.Add(ISA);
m_LiveReg.Add("");
cmbAsic.Items.Add(Asic);
if (cmbAsic.Items.Count == 1)
cmbAsic.SelectedIndex = 0;
}
public void AddResult(string Asic, string IL, string ISA, string LiveReg)
{
m_IL.Add(IL);
m_ISA.Add(ISA);
m_LiveReg.Add(LiveReg);
cmbAsic.Items.Add(Asic);
if (cmbAsic.Items.Count == 1)
cmbAsic.SelectedIndex = 0;
}
public void SetAsic(string name)
{
int index = cmbAsic.Items.IndexOf(name);
if (index == -1)
{
txtIL.Text = "";
txtISA.Text = "";
txtLiveReg.Text = "";
return;
}
// invokes handler below indirectly
cmbAsic.SelectedIndex = index;
}
private void cmbAsic_SelectedIndexChanged(object sender, EventArgs e)
{
txtIL.Text = m_IL[cmbAsic.SelectedIndex];
txtISA.Text = m_ISA[cmbAsic.SelectedIndex];
txtLiveReg.Text = m_LiveReg[cmbAsic.SelectedIndex];
if( AsicChanged != null )
AsicChanged((string)cmbAsic.SelectedItem);
}
}
}
================================================
FILE: src/Backends/CodeXLResultsPanel.resx
================================================
text/microsoft-resx2.0System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089TrueTrueTrueTrue
================================================
FILE: src/Backends/FXCBackend.cs
================================================
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
namespace Pyramid
{
class FXCResultSet : IResultSet
{
private FXCResultsPanel m_Panel = null;
public FXCResultSet(HLSLShader shader)
{
m_Panel = new FXCResultsPanel(shader);
}
public string Name { get { return "D3DCompiler"; } }
public Control AnalysisPanel { get { return null; } }
public Control ResultsPanel { get { return m_Panel; } }
};
class D3DCompilerBackend : IBackend
{
private ID3DCompiler m_Compiler;
private IDXILCompiler m_DXIL;
public string Name { get { return "D3DCompiler"; } }
public D3DCompilerBackend( ID3DCompiler comp, IDXILCompiler dxil )
{
m_Compiler = comp;
m_DXIL = dxil;
}
public IResultSet Compile(IShader shader, IBackendOptions options)
{
if (!(shader is HLSLShader ) )
return null;
HLSLShader hlsl = (HLSLShader)shader;
IHLSLOptions hlslOpts = hlsl.CompileOptions;
string text = hlsl.Code;
if (!hlsl.WasCompiled)
hlsl.Compile(m_Compiler, m_DXIL);
if (!hlsl.RootSigWasCompiled)
hlsl.CompileRootSignature(m_DXIL);
return new FXCResultSet(hlsl);
}
}
}
================================================
FILE: src/Backends/FXCResultsPanel.Designer.cs
================================================
namespace Pyramid
{
partial class FXCResultsPanel
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.tabControl1 = new System.Windows.Forms.TabControl();
this.asmPage = new System.Windows.Forms.TabPage();
this.txtASM = new System.Windows.Forms.TextBox();
this.hexPage = new System.Windows.Forms.TabPage();
this.txtHex = new System.Windows.Forms.TextBox();
this.messagesPage = new System.Windows.Forms.TabPage();
this.txtMessages = new System.Windows.Forms.TextBox();
this.rootSigPage = new System.Windows.Forms.TabPage();
this.exportPage = new System.Windows.Forms.TabPage();
this.txtRootSig = new System.Windows.Forms.TextBox();
this.btnExportBytecode = new System.Windows.Forms.Button();
this.btnExportRootSig = new System.Windows.Forms.Button();
this.btnExportCPP = new System.Windows.Forms.Button();
this.tabControl1.SuspendLayout();
this.asmPage.SuspendLayout();
this.hexPage.SuspendLayout();
this.messagesPage.SuspendLayout();
this.rootSigPage.SuspendLayout();
this.exportPage.SuspendLayout();
this.SuspendLayout();
//
// tabControl1
//
this.tabControl1.Controls.Add(this.asmPage);
this.tabControl1.Controls.Add(this.hexPage);
this.tabControl1.Controls.Add(this.messagesPage);
this.tabControl1.Controls.Add(this.rootSigPage);
this.tabControl1.Controls.Add(this.exportPage);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(0, 0);
this.tabControl1.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(200, 185);
this.tabControl1.TabIndex = 0;
//
// asmPage
//
this.asmPage.Controls.Add(this.txtASM);
this.asmPage.Location = new System.Drawing.Point(4, 25);
this.asmPage.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.asmPage.Name = "asmPage";
this.asmPage.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.asmPage.Size = new System.Drawing.Size(192, 156);
this.asmPage.TabIndex = 0;
this.asmPage.Text = "ASM";
this.asmPage.UseVisualStyleBackColor = true;
//
// txtASM
//
this.txtASM.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtASM.Location = new System.Drawing.Point(4, 4);
this.txtASM.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.txtASM.Multiline = true;
this.txtASM.Name = "txtASM";
this.txtASM.ReadOnly = true;
this.txtASM.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtASM.Size = new System.Drawing.Size(184, 148);
this.txtASM.TabIndex = 0;
//
// hexPage
//
this.hexPage.Controls.Add(this.txtHex);
this.hexPage.Location = new System.Drawing.Point(4, 25);
this.hexPage.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.hexPage.Name = "hexPage";
this.hexPage.Size = new System.Drawing.Size(192, 156);
this.hexPage.TabIndex = 2;
this.hexPage.Text = "Hex";
this.hexPage.UseVisualStyleBackColor = true;
//
// txtHex
//
this.txtHex.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtHex.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtHex.Location = new System.Drawing.Point(0, 0);
this.txtHex.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.txtHex.Multiline = true;
this.txtHex.Name = "txtHex";
this.txtHex.ReadOnly = true;
this.txtHex.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtHex.Size = new System.Drawing.Size(192, 156);
this.txtHex.TabIndex = 3;
//
// messagesPage
//
this.messagesPage.Controls.Add(this.txtMessages);
this.messagesPage.Location = new System.Drawing.Point(4, 25);
this.messagesPage.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.messagesPage.Name = "messagesPage";
this.messagesPage.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.messagesPage.Size = new System.Drawing.Size(192, 156);
this.messagesPage.TabIndex = 1;
this.messagesPage.Text = "Messages";
this.messagesPage.UseVisualStyleBackColor = true;
//
// txtMessages
//
this.txtMessages.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtMessages.Location = new System.Drawing.Point(4, 4);
this.txtMessages.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.txtMessages.Multiline = true;
this.txtMessages.Name = "txtMessages";
this.txtMessages.ReadOnly = true;
this.txtMessages.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtMessages.Size = new System.Drawing.Size(184, 148);
this.txtMessages.TabIndex = 1;
//
// rootSigPage
//
this.rootSigPage.Controls.Add(this.txtRootSig);
this.rootSigPage.Location = new System.Drawing.Point(4, 25);
this.rootSigPage.Name = "rootSigPage";
this.rootSigPage.Size = new System.Drawing.Size(192, 156);
this.rootSigPage.TabIndex = 3;
this.rootSigPage.Text = "RootSig";
this.rootSigPage.UseVisualStyleBackColor = true;
//
// exportPage
//
this.exportPage.Controls.Add(this.btnExportCPP);
this.exportPage.Controls.Add(this.btnExportRootSig);
this.exportPage.Controls.Add(this.btnExportBytecode);
this.exportPage.Location = new System.Drawing.Point(4, 25);
this.exportPage.Name = "exportPage";
this.exportPage.Size = new System.Drawing.Size(192, 156);
this.exportPage.TabIndex = 4;
this.exportPage.Text = "Export";
this.exportPage.UseVisualStyleBackColor = true;
//
// txtRootSig
//
this.txtRootSig.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtRootSig.Font = new System.Drawing.Font("Consolas", 8.5F);
this.txtRootSig.Location = new System.Drawing.Point(0, 0);
this.txtRootSig.Margin = new System.Windows.Forms.Padding(4);
this.txtRootSig.Multiline = true;
this.txtRootSig.Name = "txtRootSig";
this.txtRootSig.ReadOnly = true;
this.txtRootSig.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtRootSig.Size = new System.Drawing.Size(192, 156);
this.txtRootSig.TabIndex = 2;
//
// btnExportBytecode
//
this.btnExportBytecode.Location = new System.Drawing.Point(12, 18);
this.btnExportBytecode.Name = "btnExportBytecode";
this.btnExportBytecode.Size = new System.Drawing.Size(134, 35);
this.btnExportBytecode.TabIndex = 0;
this.btnExportBytecode.Text = "Save Bytecode";
this.btnExportBytecode.UseVisualStyleBackColor = true;
this.btnExportBytecode.Click += new System.EventHandler(this.btnExportBytecode_Click);
//
// btnExportRootSig
//
this.btnExportRootSig.Location = new System.Drawing.Point(12, 59);
this.btnExportRootSig.Name = "btnExportRootSig";
this.btnExportRootSig.Size = new System.Drawing.Size(134, 35);
this.btnExportRootSig.TabIndex = 1;
this.btnExportRootSig.Text = "Save RootSig";
this.btnExportRootSig.UseVisualStyleBackColor = true;
this.btnExportRootSig.Click += new System.EventHandler(this.btnExportRootSig_Click);
//
// btnExportCPP
//
this.btnExportCPP.Location = new System.Drawing.Point(12, 100);
this.btnExportCPP.Name = "btnExportCPP";
this.btnExportCPP.Size = new System.Drawing.Size(134, 35);
this.btnExportCPP.TabIndex = 2;
this.btnExportCPP.Text = "Create .cpp File";
this.btnExportCPP.UseVisualStyleBackColor = true;
this.btnExportCPP.Click += new System.EventHandler(this.btnExportCPP_Click);
//
// FXCResultsPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tabControl1);
this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.Name = "FXCResultsPanel";
this.Size = new System.Drawing.Size(200, 185);
this.tabControl1.ResumeLayout(false);
this.asmPage.ResumeLayout(false);
this.asmPage.PerformLayout();
this.hexPage.ResumeLayout(false);
this.hexPage.PerformLayout();
this.messagesPage.ResumeLayout(false);
this.messagesPage.PerformLayout();
this.rootSigPage.ResumeLayout(false);
this.rootSigPage.PerformLayout();
this.exportPage.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage messagesPage;
private System.Windows.Forms.TextBox txtASM;
private System.Windows.Forms.TextBox txtMessages;
private System.Windows.Forms.TabPage hexPage;
private System.Windows.Forms.TextBox txtHex;
private System.Windows.Forms.TabPage asmPage;
private System.Windows.Forms.TabPage rootSigPage;
private System.Windows.Forms.TextBox txtRootSig;
private System.Windows.Forms.TabPage exportPage;
private System.Windows.Forms.Button btnExportCPP;
private System.Windows.Forms.Button btnExportRootSig;
private System.Windows.Forms.Button btnExportBytecode;
}
}
================================================
FILE: src/Backends/FXCResultsPanel.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Pyramid
{
public partial class FXCResultsPanel : UserControl
{
private IDXShaderBlob m_Shader;
private IDXBlob m_RootSignature;
private static void HexBumpBlob( StringBuilder str, byte[] bytes )
{
int nBytes = bytes.Length;
if (nBytes % 4 == 0)
{
for (int i = 0; i < nBytes; i += 4)
{
int n = bytes[i] |
bytes[i + 1] << 8 |
bytes[i + 2] << 16 |
bytes[i + 3] << 24;
char c0 = Convert.ToChar(bytes[i]);
char c1 = Convert.ToChar(bytes[i+1]);
char c2 = Convert.ToChar(bytes[i+2]);
char c3 = Convert.ToChar(bytes[i+3]);
c0 = (c0 < 0x20 || c0 > 127) ? '.' : c0;
c1 = (c1 < 0x20 || c1 > 127) ? '.' : c1;
c2 = (c2 < 0x20 || c2 > 127) ? '.' : c2;
c3 = (c3 < 0x20 || c3 > 127) ? '.' : c3;
str.AppendFormat("{0:X8} '{1} {2} {3} {4}' ", n, c0,c1,c2,c3 );
str.AppendLine();
}
}
else
{
for( int i=0; i= nBytes)
break;
str.AppendFormat("{0,-3}, ", bytes[i + j]);
}
str.AppendLine();
}
str.Append("};");
str.AppendLine();
}
private void btnExportCPP_Click(object sender, EventArgs e)
{
SaveFileDialog save = new SaveFileDialog();
if (save.ShowDialog() != DialogResult.Cancel)
{
StringBuilder str = new StringBuilder();
if ( m_Shader != null )
{
str.Append("#if 0");
str.AppendLine();
str.Append(m_Shader.Disassemble());
str.AppendLine();
str.Append("#endif");
str.AppendLine();
byte[] byteCode = m_Shader.ReadBytes();
DeclareByteArray(str, byteCode, "Bytecode");
}
if( m_RootSignature != null )
{
byte[] byteCode = m_RootSignature.ReadBytes();
DeclareByteArray(str, byteCode, "RootSig");
}
File.WriteAllText(save.FileName, str.ToString());
}
}
}
}
================================================
FILE: src/Backends/FXCResultsPanel.resx
================================================
text/microsoft-resx2.0System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
================================================
FILE: src/Backends/GLSLOptimizerBackend.cs
================================================
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Pyramid
{
class GLSLOptimizerResultSet : IResultSet
{
private TextBox m_AnalysisPanel = new TextBox();
private TabControl m_ResultsPanel = new TabControl();
public GLSLOptimizerResultSet(GLSLOptimizer.IShader shader)
{
m_ResultsPanel.Dock = DockStyle.Fill;
TabPage page;
string AnalysisText="";
if( !shader.HadError )
{
AnalysisText = String.Format("GLSLOptimizer stats:\r\nMathOps:\t{0}\r\nTextureOps:\t{1}\r\nFlowOps:\t{2}\r\n",
shader.MathOps,
shader.TextureOps,
shader.ControlFlowOps);
m_ResultsPanel.TabPages.Add("Optimized Output");
page = m_ResultsPanel.TabPages[m_ResultsPanel.TabPages.Count - 1];
TextBox txtOutput = new TextBox();
txtOutput.ReadOnly = true;
txtOutput.Dock = DockStyle.Fill;
txtOutput.Multiline = true;
txtOutput.ScrollBars = ScrollBars.Both;
txtOutput.Text = shader.Output.Replace("\n", Environment.NewLine) ;
txtOutput.WordWrap = false;
page.Controls.Add(txtOutput);
m_ResultsPanel.TabPages.Add("Raw Output");
page = m_ResultsPanel.TabPages[m_ResultsPanel.TabPages.Count - 1];
TextBox txtRawOutput = new TextBox();
txtRawOutput.ReadOnly = true;
txtRawOutput.Dock = DockStyle.Fill;
txtRawOutput.Multiline = true;
txtRawOutput.ScrollBars = ScrollBars.Both;
txtRawOutput.Text = shader.RawOutput.Replace("\n",Environment.NewLine);
txtRawOutput.WordWrap = false;
page.Controls.Add(txtRawOutput);
}
m_ResultsPanel.TabPages.Add("Log");
page = m_ResultsPanel.TabPages[m_ResultsPanel.TabPages.Count - 1];
TextBox txtLog = new TextBox();
txtLog.ReadOnly = true;
txtLog.Dock = DockStyle.Fill;
txtLog.Multiline = true;
txtLog.ScrollBars = ScrollBars.Both;
txtLog.WordWrap = false;
txtLog.Text = shader.Log.Replace("\n", Environment.NewLine);
page.Controls.Add(txtLog);
m_AnalysisPanel.ReadOnly = true;
m_AnalysisPanel.Dock = DockStyle.Fill;
m_AnalysisPanel.Text = AnalysisText;
m_AnalysisPanel.Multiline = true;
m_AnalysisPanel.Font = new System.Drawing.Font("Lucida Console", 8);
}
public string Name { get { return "GLSLOptimizer"; } }
public Control AnalysisPanel { get { return m_AnalysisPanel; } }
public Control ResultsPanel { get { return m_ResultsPanel; } }
};
class GLSLOptimizerBackend : IBackend
{
private Dictionary m_Optimizers =
new Dictionary();
public string Name { get { return "GLSLOptimizer"; } }
public GLSLOptimizerBackend(IWrapper wrapper)
{
foreach( GLSLOptimizer.Target t in Enum.GetValues(typeof(GLSLOptimizer.Target)))
m_Optimizers.Add( t, wrapper.CreateGLSLOptimizer(t));
}
public IResultSet Compile(IShader shader, IBackendOptions options)
{
if ( !(shader is GLSLShader ) )
return null;
GLSLShader sh = (GLSLShader)shader;
IGLSLOptions glOpts = sh.CompileOptions;
if (glOpts.OptimizerOptions == null)
return null;
GLSLOptimizer.IOptimizer optimizer = m_Optimizers[glOpts.OptimizerTarget];
return new GLSLOptimizerResultSet( optimizer.Optimize(sh.Code, glOpts.OptimizerOptions) );
}
}
}
================================================
FILE: src/Backends/GLSlangBackend.cs
================================================
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Pyramid
{
class GLSlangBackend : IBackend
{
private GLSlang.ICompiler m_Compiler;
private GLSlang.IConfig m_Config;
private class GLSLangResultSet : IResultSet
{
private GLSlangResultsPanel m_Results = null;
public string Name { get { return "GLSlang"; } }
public Control AnalysisPanel { get { return null; } }
public Control ResultsPanel { get { return m_Results; } }
public GLSLangResultSet(GLSlang.IShader shader)
{
m_Results = new GLSlangResultsPanel(shader, shader.CompileSPIRV());
}
}
public string Name { get { return "GLSlang"; } }
public GLSlangBackend( IWrapper wrapper, IIncludeHandler handler )
{
m_Compiler = wrapper.CreateGLSlangCompiler(handler);
m_Config = m_Compiler.CreateDefaultConfig();
}
public IResultSet Compile(IShader shader, IBackendOptions options)
{
if (shader is GLSLShader)
{
GLSLShader sh = (GLSLShader)shader;
IGLSLOptions glOpts = sh.CompileOptions;
GLSlang.IShader result = m_Compiler.Compile(sh.Code, glOpts.ShaderType, m_Config, shader.SourceFilePath );
return new GLSLangResultSet(result);
}
else if( shader is HLSLShader )
{
HLSLShader sh = (HLSLShader)shader;
IHLSLOptions hlslOpts = sh.CompileOptions;
GLSlang.IShader result = m_Compiler.CompileHLSL(sh.Code, hlslOpts, m_Config, shader.SourceFilePath );
return new GLSLangResultSet(result);
}
else
{
return null;
}
}
}
}
================================================
FILE: src/Backends/GLSlangResultsPanel.Designer.cs
================================================
namespace Pyramid
{
partial class GLSlangResultsPanel
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBox1.Location = new System.Drawing.Point(3, 2);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ReadOnly = true;
this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(206, 152);
this.textBox1.TabIndex = 0;
this.textBox1.WordWrap = false;
//
// button1
//
this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.button1.Location = new System.Drawing.Point(141, 158);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(66, 21);
this.button1.TabIndex = 1;
this.button1.Text = "Export";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// GLSlangResultsPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Name = "GLSlangResultsPanel";
this.Size = new System.Drawing.Size(212, 183);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
}
}
================================================
FILE: src/Backends/GLSlangResultsPanel.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Pyramid
{
public partial class GLSlangResultsPanel : UserControl
{
private GLSlang.IShader m_Shader;
private SPIRV.IProgram m_SPIRV;
public GLSlangResultsPanel(GLSlang.IShader shader, SPIRV.IProgram spirv)
{
InitializeComponent();
m_Shader = shader;
m_SPIRV = spirv;
if (spirv != null)
{
textBox1.Text = spirv.Disassemble();
button1.Enabled = true;
}
else
{
textBox1.Text = shader.InfoLog.Replace("\n", Environment.NewLine);
button1.Enabled = false;
}
}
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog sd = new SaveFileDialog();
sd.Title = "Export SPIRV Binary";
if( sd.ShowDialog() != DialogResult.Cancel )
{
try
{
System.IO.File.WriteAllBytes(sd.FileName, m_SPIRV.GetBytes());
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
}
================================================
FILE: src/Backends/GLSlangResultsPanel.resx
================================================
text/microsoft-resx2.0System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
================================================
FILE: src/Backends/IBackend.cs
================================================
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Pyramid
{
public interface IResultSet
{
string Name { get; }
Control AnalysisPanel { get; }
Control ResultsPanel { get; }
}
public interface IBackendOptions
{
}
public interface IBackend
{
string Name { get; }
IResultSet Compile(IShader shader, IBackendOptions options);
}
}
================================================
FILE: src/Backends/IntelShaderAnalyzerBackend.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;
using System.Diagnostics;
namespace Pyramid
{
class IntelShaderAnalyzerResultSet : IResultSet
{
public string Name { get { return "IntelShaderAnalyzer"; } }
public Control AnalysisPanel { get { return m_Analysis; } }
public Control ResultsPanel { get { return m_Results; } }
private TextBox m_Analysis = new TextBox();
private IntelShaderAnalyzerResultsPanel m_Results = null;
public IntelShaderAnalyzerResultSet(IntelShaderAnalyzerResultsPanel panel )
{
m_Results = panel;
m_Analysis.Dock = DockStyle.Fill;
m_Analysis.ReadOnly = true;
m_Analysis.Multiline = true;
m_Analysis.Font = new System.Drawing.Font("Lucida Console", 8);
}
}
public class IntelShaderAnalyzerBackend : IBackend
{
private string m_ToolPath;
private string m_TempPath;
public IntelShaderAnalyzerBackend(Options PyramidOpts)
{
m_ToolPath = PyramidOpts.IntelShaderAnalyzerPath;
m_TempPath = PyramidOpts.TempPath;
}
public string Name { get { return "IGC"; } }
public List GetAsicList()
{
try
{
ProcessStartInfo pi = new ProcessStartInfo();
pi.RedirectStandardOutput = true;
pi.RedirectStandardInput = false;
pi.RedirectStandardError = true;
pi.CreateNoWindow = true;
pi.Arguments = "--list-asics";
pi.FileName = m_ToolPath;
pi.UseShellExecute = false;
Process p = Process.Start(pi);
int pid = p.Id;
// NOTE: Must read stdout before waiting for exit
// If we don't, then the process will hang if some stdout buffer fills up
// lame....
string stdout = p.StandardOutput.ReadToEnd();
p.WaitForExit();
p.Close();
string[] lines = stdout.Split(
new[] { "\r\n", "\r", "\n" },
StringSplitOptions.None
);
List asics = new List();
foreach( string s in lines )
{
string asic = s.Trim();
if (!string.IsNullOrEmpty(asic))
asics.Add(asic);
}
return asics;
}
catch( System.Exception ex )
{
MessageBox.Show("Failed to get asic list from IntelShaderAnalyzer");
return new List();
}
}
public IResultSet Compile(IShader shader, IBackendOptions options)
{
if (shader.Language == Languages.HLSL)
return CompileHLSL(shader as HLSLShader, options);
else
return null;
}
private IResultSet CompileHLSL(HLSLShader shader, IBackendOptions opts)
{
if (shader.CompiledBlob == null)
return null;
if (shader.CompiledBlob is IDXILShaderBlob &&
shader.CompiledRootSig == null)
return null;
try
{
List tempFilesToDelete = new List();
string byteCodeFile = Path.Combine(m_TempPath, "IGCShader");
string rootSigFile = Path.Combine(m_TempPath, "IGCRS");
File.WriteAllBytes( byteCodeFile, shader.CompiledBlob.ReadBytes() );
tempFilesToDelete.Add(byteCodeFile);
if( shader.CompiledRootSig != null )
{
File.WriteAllBytes(rootSigFile, shader.CompiledRootSig.ReadBytes());
tempFilesToDelete.Add(rootSigFile);
}
string commandline11 = "";
string commandline12 = "";
if (shader.CompiledBlob is IDXBCShaderBlob)
{
commandline11 = String.Format("--api dx11 \"{0}\"", byteCodeFile);
commandline12 = String.Format("--api dx12 \"{0}\" --rootsig_file \"{1}\"", byteCodeFile, rootSigFile);
}
else
{
commandline12 = String.Format("--api dx12 \"{0}\" --rootsig_file \"{1}\"", byteCodeFile, rootSigFile);
}
List asics = GetAsicList();
foreach (string asic in asics)
{
commandline11 = String.Concat(commandline11, String.Format(" --asic {0} ", asic));
commandline12 = String.Concat(commandline12, String.Format(" --asic {0} ", asic));
}
string isaDir11 = Path.Combine(m_TempPath, "IntelISA_11\\");
string isaDir12 = Path.Combine(m_TempPath, "IntelISA_12\\");
Directory.CreateDirectory(isaDir11);
Directory.CreateDirectory(isaDir12);
// NOTE: Extra \ is required because DOS command interpretter parses \" as a double quote
commandline11 = String.Concat(commandline11, String.Format("--isa \"{0}\\\"", isaDir11));
commandline12 = String.Concat(commandline12, String.Format("--isa \"{0}\\\"", isaDir12));
string stdout = "";
List dx11Files = new List();
List dx12Files = new List();
// DX11 requires DXBC
if( shader.CompiledBlob is IDXBCShaderBlob)
{
ProcessStartInfo pi = new ProcessStartInfo();
pi.RedirectStandardOutput = true;
pi.RedirectStandardInput = false;
pi.RedirectStandardError = true;
pi.CreateNoWindow = true;
pi.Arguments = commandline11;
pi.FileName = m_ToolPath;
pi.UseShellExecute = false;
Process p = Process.Start(pi);
int pid = p.Id;
// NOTE: Must read stdout before waiting for exit
// If we don't, then the process will hang if some stdout buffer fills up
// lame....
stdout = String.Concat("DX11 COMMAND LINE:", commandline11, Environment.NewLine);
stdout = String.Concat(stdout, p.StandardOutput.ReadToEnd());
p.WaitForExit();
p.Close();
foreach (string asic in asics)
dx11Files.Add(String.Concat(isaDir11, asic, ".asm"));
}
// DX12 requires a root signature
if( shader.CompiledRootSig != null )
{
ProcessStartInfo pi = new ProcessStartInfo();
pi.RedirectStandardOutput = true;
pi.RedirectStandardInput = false;
pi.RedirectStandardError = true;
pi.CreateNoWindow = true;
pi.Arguments = commandline12;
pi.FileName = m_ToolPath;
pi.UseShellExecute = false;
Process p = Process.Start(pi);
int pid = p.Id;
// NOTE: Must read stdout before waiting for exit
// If we don't, then the process will hang if some stdout buffer fills up
// lame....
stdout = String.Concat(stdout, string.Concat("DX12 COMMAND LINE: ", commandline12, Environment.NewLine));
stdout = String.Concat(stdout, Environment.NewLine);
stdout = String.Concat(stdout, p.StandardOutput.ReadToEnd());
p.WaitForExit();
p.Close();
foreach (string asic in asics)
dx12Files.Add(String.Concat(isaDir12, asic, ".asm"));
}
tempFilesToDelete.AddRange(dx11Files);
tempFilesToDelete.AddRange(dx12Files);
IntelShaderAnalyzerResultsPanel panel = new IntelShaderAnalyzerResultsPanel(stdout,asics);
panel.AddResults("DX11", dx11Files);
panel.AddResults("DX12", dx12Files);
// cleanup the temp files
foreach (string file in tempFilesToDelete)
File.Delete(file);
Directory.Delete(Path.Combine(m_TempPath, "IntelISA_11"));
Directory.Delete(Path.Combine(m_TempPath, "IntelISA_12"));
return new IntelShaderAnalyzerResultSet(panel);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "uh-oh, Couldn't run IntelShaderAnalyzer", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
}
};
}
================================================
FILE: src/Backends/IntelShaderAnalyzerResultsPanel.Designer.cs
================================================
namespace Pyramid
{
partial class IntelShaderAnalyzerResultsPanel
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.cmbOutputFile = new System.Windows.Forms.ComboBox();
this.cmbAPI = new System.Windows.Forms.ComboBox();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.txtAsm = new System.Windows.Forms.TextBox();
this.txtMessages = new System.Windows.Forms.TextBox();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.SuspendLayout();
//
// cmbOutputFile
//
this.cmbOutputFile.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbOutputFile.FormattingEnabled = true;
this.cmbOutputFile.Location = new System.Drawing.Point(161, 19);
this.cmbOutputFile.Margin = new System.Windows.Forms.Padding(4);
this.cmbOutputFile.Name = "cmbOutputFile";
this.cmbOutputFile.Size = new System.Drawing.Size(250, 24);
this.cmbOutputFile.TabIndex = 5;
this.cmbOutputFile.SelectedIndexChanged += new System.EventHandler(this.cmbOutputFile_SelectedIndexChanged);
//
// cmbAPI
//
this.cmbAPI.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbAPI.FormattingEnabled = true;
this.cmbAPI.Location = new System.Drawing.Point(35, 19);
this.cmbAPI.Margin = new System.Windows.Forms.Padding(4);
this.cmbAPI.Name = "cmbAPI";
this.cmbAPI.Size = new System.Drawing.Size(104, 24);
this.cmbAPI.TabIndex = 6;
this.cmbAPI.SelectedIndexChanged += new System.EventHandler(this.cmbAPI_SelectedIndexChanged);
//
// tabControl1
//
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Location = new System.Drawing.Point(3, 50);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(620, 409);
this.tabControl1.TabIndex = 7;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.txtAsm);
this.tabPage1.Location = new System.Drawing.Point(4, 25);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(612, 380);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Asm";
this.tabPage1.UseVisualStyleBackColor = true;
this.tabPage1.Click += new System.EventHandler(this.tabPage1_Click);
//
// tabPage2
//
this.tabPage2.Controls.Add(this.txtMessages);
this.tabPage2.Location = new System.Drawing.Point(4, 25);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(612, 380);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Messages";
this.tabPage2.UseVisualStyleBackColor = true;
//
// txtAsm
//
this.txtAsm.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtAsm.Font = new System.Drawing.Font("Consolas", 9F);
this.txtAsm.Location = new System.Drawing.Point(3, 3);
this.txtAsm.Margin = new System.Windows.Forms.Padding(4);
this.txtAsm.Multiline = true;
this.txtAsm.Name = "txtAsm";
this.txtAsm.ReadOnly = true;
this.txtAsm.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtAsm.Size = new System.Drawing.Size(606, 374);
this.txtAsm.TabIndex = 5;
this.txtAsm.WordWrap = false;
//
// txtMessages
//
this.txtMessages.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtMessages.Font = new System.Drawing.Font("Consolas", 9F);
this.txtMessages.Location = new System.Drawing.Point(3, 3);
this.txtMessages.Margin = new System.Windows.Forms.Padding(4);
this.txtMessages.Multiline = true;
this.txtMessages.Name = "txtMessages";
this.txtMessages.ReadOnly = true;
this.txtMessages.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtMessages.Size = new System.Drawing.Size(606, 374);
this.txtMessages.TabIndex = 6;
//
// IntelShaderAnalyzerResultsPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tabControl1);
this.Controls.Add(this.cmbAPI);
this.Controls.Add(this.cmbOutputFile);
this.Name = "IntelShaderAnalyzerResultsPanel";
this.Size = new System.Drawing.Size(623, 462);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage1.PerformLayout();
this.tabPage2.ResumeLayout(false);
this.tabPage2.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox cmbOutputFile;
private System.Windows.Forms.ComboBox cmbAPI;
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TextBox txtAsm;
private System.Windows.Forms.TextBox txtMessages;
}
}
================================================
FILE: src/Backends/IntelShaderAnalyzerResultsPanel.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Pyramid
{
public partial class IntelShaderAnalyzerResultsPanel : UserControl
{
public IntelShaderAnalyzerResultsPanel( string stdout, List asics )
{
InitializeComponent();
txtMessages.Text = stdout;
tabPage1.Visible = false;
foreach( string asic in asics )
cmbOutputFile.Items.Add(asic);
cmbOutputFile.SelectedIndex = 0;
}
private Dictionary > m_APISets = new Dictionary>();
public void AddResults( string api, List files )
{
if (files.Count == 0)
return;
Dictionary asicFiles = new Dictionary();
foreach( string path in files )
{
string asic = Path.GetFileNameWithoutExtension(path);
if (File.Exists(path))
{
string asm = File.ReadAllText(path);
asicFiles.Add(asic, asm);
}
}
m_APISets.Add(api, asicFiles);
cmbAPI.Items.Add(api);
cmbAPI.SelectedIndex = 0;
RefreshAsm();
}
private void RefreshAsm()
{
txtAsm.Text = "";
if( cmbAPI.SelectedItem != null && cmbOutputFile.SelectedItem != null )
{
Dictionary Files;
if (m_APISets.TryGetValue((string)cmbAPI.SelectedItem, out Files))
{
string text;
if (Files.TryGetValue((string)cmbOutputFile.SelectedItem, out text))
{
txtAsm.Text = text;
}
}
}
}
private void tabPage1_Click(object sender, EventArgs e)
{
}
private void cmbAPI_SelectedIndexChanged(object sender, EventArgs e)
{
RefreshAsm();
}
private void cmbOutputFile_SelectedIndexChanged(object sender, EventArgs e)
{
RefreshAsm();
}
}
}
================================================
FILE: src/Backends/IntelShaderAnalyzerResultsPanel.resx
================================================
text/microsoft-resx2.0System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
================================================
FILE: src/Backends/MaliSCBackend.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace Pyramid
{
public class MaliSCResultSet : IResultSet
{
public string Name { get { return "MaliSC"; } }
public Control AnalysisPanel { get; private set; }
public Control ResultsPanel { get; private set; }
public MaliSCResultSet()
{
AnalysisPanel = null;
ResultsPanel = new MaliSCResultsPanel();
}
public void Add(string core, string output)
{
MaliSCResultsPanel rp = ResultsPanel as MaliSCResultsPanel;
rp.AddResult(core, output);
}
}
public class MaliSCBackend : IBackend
{
private string m_MaliRoot = "";
private string m_TempPath = "";
private List m_Asics = new List();
public MaliSCBackend(string MaliRoot, string TempPath)
{
m_MaliRoot = MaliRoot;
m_TempPath = TempPath;
// get asic list
string CommandLine = string.Format("--help");
ProcessStartInfo pi = new ProcessStartInfo();
pi.RedirectStandardOutput = true;
pi.RedirectStandardInput = true;
pi.RedirectStandardError = true;
pi.EnvironmentVariables.Add("MALICM_LOCATION", m_MaliRoot);
pi.CreateNoWindow = true;
pi.Arguments = CommandLine;
pi.FileName = Path.Combine(MaliRoot, "malisc.exe");
pi.UseShellExecute = false;
try
{
Process p = Process.Start(pi);
p.WaitForExit();
// malisc frontend prints a giant help-text string.
// amidst the noise, we'll find a list of supported cores
//
// We'll let them use defaults for driver revision and HW revision
// because permuting over all that stuff is probably fruitless
//
string output = p.StandardOutput.ReadToEnd();
int idx = output.IndexOf("[-c <");
string trimmed = output.Substring(output.IndexOf("[-c"));
trimmed = trimmed.Substring(0, trimmed.IndexOf("]"));
trimmed = trimmed.Substring(trimmed.IndexOf("<"));
trimmed = trimmed.Substring(0, trimmed.IndexOf(">"));
trimmed = trimmed.Substring(1);
string[] asics = trimmed.Split('|');
foreach (string s in asics)
m_Asics.Add(s.Trim());
}
catch (Exception e)
{
MessageBox.Show(e.Message, "uh-oh, couldn't get MaliSC asic list", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public string Name { get { return "MaliSC"; } }
public IResultSet Compile(IShader sh, IBackendOptions options)
{
if (sh.Language != Languages.GLSL)
return null;
GLSLShader glShader = (GLSLShader)sh;
IGLSLOptions glOpts = glShader.CompileOptions;
string shader = glShader.Code;
string shaderType = "";
switch( glOpts.ShaderType )
{
case GLSLShaderType.VERTEX: shaderType = "--vertex"; break;
case GLSLShaderType.FRAGMENT: shaderType = "--fragment"; break;
case GLSLShaderType.COMPUTE: shaderType = "--compute"; break;
default:
return null;
}
string tmpFile = Path.Combine(m_TempPath, "PYRAMID_mali");
try
{
StreamWriter stream = File.CreateText(tmpFile);
stream.Write(shader);
stream.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message, "uh-oh, couldn't create temp file", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
MaliSCResultSet rs = new MaliSCResultSet();
try
{
foreach (string asic in m_Asics)
{
string commandline = String.Format("-V {0} -c {1} {2}", shaderType, asic, tmpFile);
ProcessStartInfo pi = new ProcessStartInfo();
pi.RedirectStandardOutput = true;
pi.RedirectStandardInput = true;
pi.RedirectStandardError = true;
pi.EnvironmentVariables.Add("MALICM_LOCATION", m_MaliRoot);
pi.CreateNoWindow = true;
pi.Arguments = commandline;
pi.FileName = Path.Combine(m_MaliRoot, "malisc.exe");
pi.UseShellExecute = false;
Process p = Process.Start(pi);
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
rs.Add(asic, output);
}
}
catch (System.Exception e)
{
MessageBox.Show(e.Message, "uh-oh, couldn't run MaliSC", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
File.Delete(tmpFile);
return rs;
}
}
}
================================================
FILE: src/Backends/MaliSCResultsPanel.Designer.cs
================================================
namespace Pyramid
{
partial class MaliSCResultsPanel
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.txtOutput = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.cmbCore = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// txtOutput
//
this.txtOutput.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtOutput.Location = new System.Drawing.Point(3, 32);
this.txtOutput.Multiline = true;
this.txtOutput.Name = "txtOutput";
this.txtOutput.ReadOnly = true;
this.txtOutput.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtOutput.Size = new System.Drawing.Size(393, 283);
this.txtOutput.TabIndex = 0;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(8, 11);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(29, 13);
this.label1.TabIndex = 1;
this.label1.Text = "Core";
//
// cmbCore
//
this.cmbCore.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbCore.FormattingEnabled = true;
this.cmbCore.Location = new System.Drawing.Point(43, 5);
this.cmbCore.Name = "cmbCore";
this.cmbCore.Size = new System.Drawing.Size(207, 21);
this.cmbCore.TabIndex = 2;
this.cmbCore.SelectedIndexChanged += new System.EventHandler(this.cmbCore_SelectedIndexChanged);
//
// MaliSCResultsPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.cmbCore);
this.Controls.Add(this.label1);
this.Controls.Add(this.txtOutput);
this.Name = "MaliSCResultsPanel";
this.Size = new System.Drawing.Size(399, 318);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox txtOutput;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ComboBox cmbCore;
}
}
================================================
FILE: src/Backends/MaliSCResultsPanel.cs
================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Pyramid
{
public partial class MaliSCResultsPanel : UserControl
{
private List m_Cores = new List();
private List m_Output = new List();
public MaliSCResultsPanel()
{
InitializeComponent();
}
public void AddResult(string core, string output)
{
m_Cores.Add(core);
m_Output.Add(output);
cmbCore.Items.Add(core);
if (cmbCore.Items.Count == 1)
cmbCore.SelectedIndex = 0;
}
private void cmbCore_SelectedIndexChanged(object sender, EventArgs e)
{
txtOutput.Text = m_Output[m_Cores.IndexOf(cmbCore.Text)];
}
}
}
================================================
FILE: src/Backends/MaliSCResultsPanel.resx
================================================
text/microsoft-resx2.0System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
================================================
FILE: src/Backends/PVRResultsPanel.Designer.cs
================================================
namespace Pyramid
{
partial class PVRResultsPanel
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.cmbCompiler = new System.Windows.Forms.ComboBox();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.txtASM = new System.Windows.Forms.TextBox();
this.txtOutput = new System.Windows.Forms.TextBox();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(5, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(47, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Compiler";
//
// cmbCompiler
//
this.cmbCompiler.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.cmbCompiler.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbCompiler.FormattingEnabled = true;
this.cmbCompiler.Location = new System.Drawing.Point(54, 5);
this.cmbCompiler.Name = "cmbCompiler";
this.cmbCompiler.Size = new System.Drawing.Size(164, 21);
this.cmbCompiler.TabIndex = 1;
this.cmbCompiler.SelectedIndexChanged += new System.EventHandler(this.cmbCompiler_SelectedIndexChanged);
//
// tabControl1
//
this.tabControl1.Alignment = System.Windows.Forms.TabAlignment.Bottom;
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Location = new System.Drawing.Point(10, 31);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(207, 190);
this.tabControl1.TabIndex = 2;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.txtASM);
this.tabPage1.Location = new System.Drawing.Point(4, 4);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(199, 164);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "ASM";
this.tabPage1.UseVisualStyleBackColor = true;
//
// tabPage2
//
this.tabPage2.Controls.Add(this.txtOutput);
this.tabPage2.Location = new System.Drawing.Point(4, 4);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(199, 164);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Output";
this.tabPage2.UseVisualStyleBackColor = true;
//
// txtASM
//
this.txtASM.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtASM.Location = new System.Drawing.Point(3, 3);
this.txtASM.Multiline = true;
this.txtASM.Name = "txtASM";
this.txtASM.ReadOnly = true;
this.txtASM.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtASM.Size = new System.Drawing.Size(193, 158);
this.txtASM.TabIndex = 0;
//
// txtOutput
//
this.txtOutput.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtOutput.Location = new System.Drawing.Point(3, 3);
this.txtOutput.Multiline = true;
this.txtOutput.Name = "txtOutput";
this.txtOutput.ReadOnly = true;
this.txtOutput.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtOutput.Size = new System.Drawing.Size(193, 158);
this.txtOutput.TabIndex = 1;
//
// PVRResultsPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tabControl1);
this.Controls.Add(this.cmbCompiler);
this.Controls.Add(this.label1);
this.Name = "PVRResultsPanel";
this.Size = new System.Drawing.Size(228, 232);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage1.PerformLayout();
this.tabPage2.ResumeLayout(false);
this.tabPage2.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ComboBox cmbCompiler;
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TextBox txtASM;
private System.Windows.Forms.TextBox txtOutput;
}
}
================================================
FILE: src/Backends/PVRResultsPanel.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
namespace Pyramid
{
public partial class PVRResultsPanel : UserControl
{
private List m_ASM = new List();
private List m_Output = new List();
public PVRResultsPanel()
{
InitializeComponent();
}
public void AddResult( string compiler, string output, string asm )
{
m_ASM.Add(asm);
m_Output.Add( output );
cmbCompiler.Items.Add(compiler);
if( cmbCompiler.Items.Count == 1 )
cmbCompiler.SelectedIndex = 0;
}
private void cmbCompiler_SelectedIndexChanged(object sender, EventArgs e)
{
txtASM.Text = m_ASM[cmbCompiler.SelectedIndex];
txtOutput.Text = m_Output[cmbCompiler.SelectedIndex];
}
}
}
================================================
FILE: src/Backends/PVRResultsPanel.resx
================================================
text/microsoft-resx2.0System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089TrueTrue
================================================
FILE: src/Backends/PowerVRBackend.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Windows.Forms;
namespace Pyramid
{
class PVRResultSet : IResultSet
{
private PVRResultsPanel m_Results = new PVRResultsPanel();
public string Name { get { return "PowerVR"; } }
public Control AnalysisPanel { get { return null; } }
public Control ResultsPanel { get { return m_Results; } }
public PVRResultsPanel PVRResultsPanel { get { return m_Results; } }
};
class PowerVRBackend : IBackend
{
private List m_Compilers = new List();
private string m_TempPath;
public string Name { get { return "PowerVR"; } }
public PowerVRBackend( string CompilerDir, string tempDir )
{
CompilerDir = Path.GetFullPath(CompilerDir);
m_TempPath = tempDir;
if (!Directory.Exists(CompilerDir))
{
MessageBox.Show("PowerVR compiler directory doesn't exist", "uh-oh", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
foreach (string s in Directory.EnumerateFiles(CompilerDir))
{
string ext = Path.GetExtension(s);
if( ext.Equals(".exe") )
{
ProcessStartInfo pi = new ProcessStartInfo();
pi.RedirectStandardOutput = true;
pi.RedirectStandardInput = true;
pi.RedirectStandardError = true;
pi.CreateNoWindow = true;
pi.Arguments = "-?";
pi.FileName = s;
pi.UseShellExecute = false;
try
{
Process p = Process.Start(pi);
p.WaitForExit();
string output = p.StandardError.ReadToEnd();
if (!output.Contains("PVR GLSL-ES compiler for"))
continue;
if (!output.Contains("-disasm"))
continue;
m_Compilers.Add(s);
}
catch (System.Exception )
{
continue;
}
}
}
}
public IResultSet Compile(IShader sh, IBackendOptions options)
{
if (sh.Language != Languages.GLSL)
return null;
GLSLShader glShader = (GLSLShader)sh;
IGLSLOptions glOpts = glShader.CompileOptions;
string shader = glShader.Code;
string shaderSwitch = "";
switch (glOpts.ShaderType)
{
case GLSLShaderType.VERTEX: shaderSwitch = "-v"; break;
case GLSLShaderType.FRAGMENT: shaderSwitch = "-f"; break;
case GLSLShaderType.COMPUTE: shaderSwitch = "-c"; break;
default:
return null;
}
string tmpFile = Path.Combine(m_TempPath, "PYRAMID_pvr");
string dummyOutputFile = Path.Combine(m_TempPath, "PYRAMID_pvr.out");
string disasmFile = Path.Combine(m_TempPath, "PYRAMID_pvr.disasm");
try
{
StreamWriter stream = File.CreateText(tmpFile);
stream.Write(shader);
stream.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message, "uh-oh, couldn't create temp file", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
string args = String.Format("{0} {1} {2} -disasm", tmpFile, dummyOutputFile, shaderSwitch);
PVRResultSet rs = new PVRResultSet();
foreach (string s in m_Compilers)
{
ProcessStartInfo pi = new ProcessStartInfo();
pi.RedirectStandardOutput = true;
pi.RedirectStandardInput = true;
pi.RedirectStandardError = true;
pi.CreateNoWindow = true;
pi.Arguments = args;
pi.FileName = s;
pi.UseShellExecute = false;
try
{
Process p= Process.Start(pi);
string asm = "No Output";
string output = p.StandardError.ReadToEnd();
string compiler = Path.GetFileNameWithoutExtension(s);
p.WaitForExit();
if (File.Exists(disasmFile))
{
asm = File.ReadAllText(disasmFile);
File.Delete(disasmFile);
}
rs.PVRResultsPanel.AddResult(compiler, output, asm);
}
catch (System.Exception)
{
continue;
}
}
File.Delete(tmpFile);
return rs;
}
}
}
================================================
FILE: src/Backends/RGABackend.cs
================================================
using System.Diagnostics;
using System.Collections.Generic;
using System.IO;
using System;
using System.Windows.Forms;
namespace Pyramid
{
class RGAResult
{
public string Isa { get; private set; }
public string Il { get; private set; }
public string Analysis { get; private set; }
public string LiveReg { get; private set; }
public string Asic { get; private set; }
public RGAResult( string asic, string path )
{
Asic = asic;
string isaFile = Path.ChangeExtension(path, ".isa");
string analysisFile = Path.ChangeExtension(path, ".analysis");
string ilFile = Path.ChangeExtension(path, ".il");
string liveRegFile = Path.ChangeExtension(path, ".livereg");
if (File.Exists(isaFile))
{
this.Isa = File.ReadAllText(isaFile);
File.Delete(isaFile);
}
if (File.Exists(analysisFile))
{
this.Analysis = File.ReadAllText(analysisFile);
File.Delete(analysisFile);
}
if (File.Exists(ilFile))
{
this.Il = File.ReadAllText(ilFile);
File.Delete(ilFile);
}
if (File.Exists(liveRegFile))
{
this.LiveReg = File.ReadAllText(liveRegFile);
File.Delete(liveRegFile);
}
}
}
class GenericTextResultSet : IResultSet
{
public GenericTextResultSet(string name, string text)
{
Name = name;
RichTextBox results = new RichTextBox();
results.Dock = DockStyle.Fill;
results.ReadOnly = true;
results.Multiline = true;
results.Font = new System.Drawing.Font("Lucida Console", 8);
results.Text = text;
results.ScrollBars = RichTextBoxScrollBars.Both;
ResultsPanel = results;
}
public Control ResultsPanel { get; private set; }
public Control AnalysisPanel { get { return null; } }
public string Name { get; private set; }
}
class RGAResultSet : IResultSet
{
private AMDResultsPanel m_ResultsPanel;
private TextBox m_Analysis = new TextBox();
private Dictionary m_ResultMap = new Dictionary();
public RGAResultSet( string name, string toolOutput )
{
m_ResultsPanel = new AMDResultsPanel();
m_ResultsPanel.SetToolOutput(toolOutput);
m_Analysis.Dock = DockStyle.Fill;
m_Analysis.ReadOnly = true;
m_Analysis.Multiline = true;
m_Analysis.Font = new System.Drawing.Font("Lucida Console", 8);
m_Analysis.ScrollBars = ScrollBars.Both;
m_ResultsPanel.AsicChanged += delegate(string asic)
{
m_Analysis.Text = m_ResultMap[asic].Analysis;
};
Name = name;
}
public Control ResultsPanel { get { return m_ResultsPanel; } }
public Control AnalysisPanel { get { return m_Analysis; } }
public string Name { get; private set; }
public int ResultCount { get { return m_ResultsPanel.ResultCount; } }
public void AddCompileResult( RGAResult result )
{
m_ResultMap.Add(result.Asic, result);
m_ResultsPanel.AddResult(result.Asic, result.Il, result.Isa);
}
public void DisplayAsic(string asic)
{
m_ResultsPanel.SetAsic(asic);
m_Analysis.Text = m_ResultMap[asic].Analysis;
}
}
class RGABackendOptions : IBackendOptions
{
private Options m_Opts;
public RGABackendOptions( Options opts )
{
m_Opts = opts;
}
public bool ShouldCompileForAsic( string asic)
{
return !m_Opts.IsRGAAsicDisabled(asic);
}
}
class RGABackend : IBackend
{
private List m_SupportedAsics = new List();
private string m_RGAPath = "";
private string m_TempPath = "";
private GLSlang.ICompiler m_GLSLang;
private GLSlang.IConfig m_GLSLangConfig;
public string Name { get { return "RGA_Vulkan"; } }
public IEnumerable Asics { get { return m_SupportedAsics; } }
public static List GetAsicList( string RGAPath )
{
string CommandLine = string.Format("-s vulkan -l");
List asics = new List();
ProcessStartInfo pi = new ProcessStartInfo();
pi.RedirectStandardOutput = true;
pi.RedirectStandardInput = true;
pi.RedirectStandardError = true;
pi.CreateNoWindow = true;
pi.Arguments = CommandLine;
pi.FileName = RGAPath;
pi.UseShellExecute = false;
try
{
Process p = Process.Start(pi);
while (!p.StandardOutput.EndOfStream)
{
// Output is of the form:
//
//name (graphics ip)
//\tproduct_name
//\tproduct_name
// ....
//
string s = p.StandardOutput.ReadLine();
if (s.Length == 0)
continue; // blank line
if (s[0] == '\t')
continue; // indented product name
// grab the asic name, ignore everything after
int len = s.IndexOf(' ');
if (len > 0)
s = s.Substring(0, len);
asics.Add(s);
}
p.WaitForExit();
p.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message, "uh-oh, couldn't get RGA asic list", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return asics;
}
public RGABackend(string RGAPath, string TempPath, IWrapper wrapper, IIncludeHandler handler )
{
m_SupportedAsics = GetAsicList(RGAPath);
m_RGAPath = RGAPath;
m_TempPath = TempPath;
m_GLSLang = wrapper.CreateGLSlangCompiler(handler);
m_GLSLangConfig = m_GLSLang.CreateDefaultConfig();
}
private string GetRGAShaderType(GLSLShaderType eShaderType)
{
string sType = "";
switch (eShaderType)
{
default:
return "";
case GLSLShaderType.VERTEX: sType = "vert"; break;
case GLSLShaderType.FRAGMENT: sType = "frag"; break;
case GLSLShaderType.GEOMETRY: sType = "geom"; break;
case GLSLShaderType.TESS_CONTROL: sType = "tesc"; break;
case GLSLShaderType.TESS_EVALUATION: sType = "tese"; break;
case GLSLShaderType.COMPUTE: sType = "comp"; break;
}
return sType;
}
GLSlang.IShader CompileShader( IShader shader )
{
if (shader is HLSLShader)
{
// pass the shader through GLSLang's hlsl front end
HLSLShader hlsl = shader as HLSLShader;
return m_GLSLang.CompileHLSL(shader.Code, hlsl.CompileOptions, m_GLSLangConfig, shader.SourceFilePath);
}
else if( shader is GLSLShader )
{
GLSLShader glsl = shader as GLSLShader;
return m_GLSLang.Compile(shader.Code, glsl.CompileOptions.ShaderType, m_GLSLangConfig, glsl.SourceFilePath);
}
else
{
throw new System.Exception("Bad shader type?!?");
}
}
public IResultSet Compile(IShader shader, IBackendOptions options)
{
if( !(options is RGABackendOptions))
return null;
if (!(shader is HLSLShader || shader is GLSLShader))
return null;
RGABackendOptions backendOptions = options as RGABackendOptions;
string tmpFile = Path.Combine(m_TempPath, "PYRAMID_amdrga");
// pass the shader through GLSLang's hlsl front end
GLSlang.IShader glShader = CompileShader(shader);
if (glShader.HasErrors)
return new GenericTextResultSet(this.Name, glShader.InfoLog);
string sType = GetRGAShaderType(glShader.ShaderType);
// get the SPIR-V
SPIRV.IProgram spirv = glShader.CompileSPIRV();
if (spirv == null)
return new GenericTextResultSet(this.Name, "Error generating SPIR-V");
// dump the SPIR-V to disk
try
{
File.WriteAllBytes(tmpFile, spirv.GetBytes());
}
catch (Exception e)
{
MessageBox.Show(e.Message, "uh-oh, couldn't create temp file", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
// send the SPIR-V to RGA
string CommandLine = String.Format(" -s vulkan-spv {0}", tmpFile);
string isaPath = Path.Combine(m_TempPath, "pyramid.isa");
string analysisPath = Path.Combine(m_TempPath, "pyramid.analysis");
string ilPath = Path.Combine(m_TempPath, "pyramid.il");
string liveRegPath = Path.Combine(m_TempPath, "pyramid.livereg");
CommandLine = String.Concat(CommandLine, String.Format(" --isa \"{0}\" ", isaPath));
CommandLine = String.Concat(CommandLine, String.Format(" -a \"{0}\" ", analysisPath));
CommandLine = String.Concat(CommandLine, String.Format(" --il \"{0}\" ", ilPath));
CommandLine = String.Concat(CommandLine, String.Format(" --livereg \"{0}\" ", liveRegPath));
List asicsToCompile = new List();
foreach (string asic in m_SupportedAsics)
{
if ( backendOptions.ShouldCompileForAsic(asic))
{
asicsToCompile.Add(asic);
CommandLine = String.Concat(CommandLine, " -c ", asic, " ");
}
}
if (asicsToCompile.Count == 0)
return null;
string defaultAsic = asicsToCompile[0];
ProcessStartInfo pi = new ProcessStartInfo();
pi.RedirectStandardOutput = true;
pi.RedirectStandardInput = true;
pi.RedirectStandardError = false;
pi.CreateNoWindow = true;
pi.Arguments = CommandLine;
pi.FileName = m_RGAPath;
pi.UseShellExecute = false;
string output;
try
{
Process p = Process.Start(pi);
output = p.StandardOutput.ReadToEnd();
int TIMEOUT = 60000;
p.WaitForExit(TIMEOUT);
p.Close();
File.Delete(tmpFile);
}
catch (Exception e)
{
MessageBox.Show(e.Message, "uh-oh, couldn't run CodeXL", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
output = String.Format(@"Arguments:
----------
{0}
Output:
-------
{1}", CommandLine, output);
// Compile results are emitted in one set of files per asic
RGAResultSet results = new RGAResultSet(this.Name, output);
foreach (string asic in asicsToCompile)
{
string path = Path.Combine( m_TempPath, String.Format("{0}_{1}_pyramid", asic, sType) );
try
{
RGAResult result = new RGAResult(asic, path);
results.AddCompileResult(result);
}
catch (Exception ex)
{
// may occur on compile error
}
}
if (results.ResultCount > 0)
{
results.DisplayAsic(defaultAsic);
return results;
}
else
return null;
}
}
}
================================================
FILE: src/GLSLOptimizer.cs
================================================
using System;
using System.Collections.Generic;
namespace Pyramid
{
namespace GLSLOptimizer
{
public enum Target
{
OPENGL = 0,
OPENGL_ES2 = 1,
OPENGL_ES3 = 2
};
public enum ShaderType
{
VERTEX = 0,
FRAGMENT = 1,
};
public interface IOptions
{
ShaderType ShaderType { get; }
uint MaxUnrollIterations { get; }
}
public interface IShader
{
bool HadError { get; }
string Output { get; }
string RawOutput { get; }
string Log { get; }
IEnumerable Inputs { get;}
int MathOps { get; }
int TextureOps { get; }
int ControlFlowOps { get; }
};
public interface IOptimizer
{
IShader Optimize(string text, IOptions opts);
};
}
}
================================================
FILE: src/GLSLTypes.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pyramid
{
public enum GLSLShaderType
{
VERTEX = 0,
FRAGMENT = 1,
TESS_CONTROL = 2,
TESS_EVALUATION = 3,
GEOMETRY = 4,
COMPUTE = 5,
}
public interface IGLSLOptions : ICompileOptions
{
GLSLShaderType ShaderType { get; }
GLSLOptimizer.Target OptimizerTarget { get; }
GLSLOptimizer.IOptions OptimizerOptions { get; }
}
public class GLSLShader : IShader
{
public GLSLShader(string code, IGLSLOptions opts, string path )
{
CompileOptions = opts;
Code = code;
SourceFilePath = path;
}
public Languages Language { get { return Languages.GLSL; } }
public IGLSLOptions CompileOptions { get; private set; }
public string Code { get; private set; }
public string SourceFilePath { get; private set; }
};
}
================================================
FILE: src/GLSlang.cs
================================================
using System;
using System.Collections.Generic;
namespace Pyramid
{
namespace GLSlang
{
public interface IShader
{
GLSLShaderType ShaderType { get; }
bool HasErrors { get; }
string InfoLog { get; }
string InfoDebugLog { get; }
SPIRV.IProgram CompileSPIRV();
}
public interface IConfig
{
}
public interface ICompiler
{
IConfig CreateConfig(string text);
IConfig CreateDefaultConfig();
IShader Compile(string text, GLSLShaderType eType, IConfig config, string filePath);
IShader CompileHLSL(string text, IHLSLOptions opts, IConfig config, string filePath );
}
}
}
================================================
FILE: src/HLSLTypes.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Pyramid
{
public enum HLSLTarget
{
vs_3_0,
vs_4_0,
vs_4_1,
vs_5_0,
vs_5_1,
vs_6_0,
vs_6_1,
vs_6_2,
ps_3_0,
ps_4_0,
ps_4_1,
ps_5_0,
ps_5_1,
ps_6_0,
ps_6_1,
ps_6_2,
gs_4_0,
gs_4_1,
gs_5_0,
gs_5_1,
gs_6_0,
gs_6_1,
gs_6_2,
hs_5_0,
hs_5_1,
hs_6_0,
hs_6_1,
hs_6_2,
ds_5_0,
ds_5_1,
ds_6_0,
ds_6_1,
ds_6_2,
cs_4_0,
cs_4_1,
cs_5_0,
cs_5_1,
cs_6_0,
cs_6_1,
cs_6_2,
};
public enum RootSignatureTarget
{
rootsig_1_0,
rootsig_1_1,
}
public enum HLSLOptimizationLevel
{
SKIP,
LEVEL0,
LEVEL1,
LEVEL2,
LEVEL3
};
public enum HLSLShaderType
{
VERTEX,
PIXEL,
GEOMETRY,
DOMAIN,
HULL,
COMPUTE
};
public interface IHLSLOptions : ICompileOptions
{
string EntryPoint { get; }
HLSLTarget Target { get; }
RootSignatureTarget RootSigTarget { get; }
HLSLShaderType ShaderType { get; }
HLSLOptimizationLevel OptimizationLevel { get; }
bool Compatibility { get; }
string RootSigMacro { get; }
string GetFXCCommandLine(string shaderFile);
uint GetD3DCompileFlagBits();
}
public interface IDXShaderReflection
{
HLSLShaderType GetShaderType();
uint GetThreadsPerGroup();
};
public interface IDXBlob
{
byte[] ReadBytes();
}
public interface IDXShaderBlob : IDXBlob
{
string Disassemble();
IDXBlob ExtractRootSignature();
}
public interface IDXILShaderBlob : IDXShaderBlob
{
}
public interface IDXBCShaderBlob : IDXShaderBlob
{
IDXBCShaderBlob GetSignatureBlob();
IDXBCShaderBlob GetExecutableBlob();
IDXBCShaderBlob Strip();
IDXShaderReflection Reflect();
}
public class HLSLShader : IShader
{
public HLSLShader(string code, IHLSLOptions opts ,string path)
{
CompileOptions = opts;
Code = code;
WasCompiled = false;
RootSigWasCompiled = false;
RootSigHasError = false;
SourceFilePath = path;
}
public Languages Language { get { return Languages.HLSL; } }
public IHLSLOptions CompileOptions { get; private set; }
public string Code { get; private set; }
public IDXShaderBlob CompiledBlob { get; private set; }
public string Messages { get; private set; }
public string SourceFilePath { get; private set; }
public bool CompileRootSignature( IDXILCompiler compiler )
{
if( compiler != null )
{
IDXBlob blob;
string msg;
RootSigHasError = !compiler.CompileRootSignature(this.Code, this.CompileOptions, this.SourceFilePath, out blob, out msg);
RootSigMessages = msg;
CompiledRootSig = blob;
RootSigWasCompiled = true;
return !RootSigHasError;
}
else
{
return false;
}
}
public bool Compile( ID3DCompiler compiler, IDXILCompiler dxil )
{
if( CompileOptions.Target.ToString()[3] == '6' )
{
if (dxil == null)
return false;
IDXILShaderBlob blob;
string msg;
HasError = !dxil.Compile(this.Code, this.CompileOptions, this.SourceFilePath, out blob, out msg);
WasCompiled = true;
Messages = msg;
CompiledBlob = blob;
}
else
{
if( compiler == null )
return false;
IDXBCShaderBlob blob;
string msg;
HasError = !compiler.Compile(this.Code, this.CompileOptions, this.SourceFilePath, out blob, out msg);
WasCompiled = true;
Messages = msg;
CompiledBlob = blob;
}
// check for embedded root signature and pull it out if there is one
if( CompiledBlob != null )
{
IDXBlob rs = CompiledBlob.ExtractRootSignature();
if (rs != null)
{
RootSigWasCompiled = true;
RootSigHasError = false;
CompiledRootSig = rs;
}
}
return !HasError;
}
public IDXBlob CompiledRootSig { get; private set; }
public bool RootSigWasCompiled { get; private set; }
public bool RootSigHasError { get; private set; }
public string RootSigMessages { get; private set; }
public bool WasCompiled { get; private set; }
public bool HasError { get; private set; }
public bool WasCompiledWithErrors { get { return WasCompiled && HasError; } }
};
public interface ID3DCompiler
{
bool CompileRootSignature(string text,
IHLSLOptions opts,
string fileName,
out IDXBlob blob,
out string Messages);
bool Compile(string text,
IHLSLOptions opts,
string fileName,
out IDXBCShaderBlob blob,
out string Messages);
};
public interface IDXILCompiler
{
bool CompileRootSignature(string text,
IHLSLOptions opts,
string fileName,
out IDXBlob blob,
out string Messages);
bool Compile(string text,
IHLSLOptions opts,
string fileName,
out IDXILShaderBlob blob,
out string Messages);
};
}
================================================
FILE: src/IAMDDriver.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pyramid
{
public interface IAMDAsic
{
string Name { get; }
};
public interface IAMDShader
{
IAMDAsic Asic { get; }
byte[] ReadISABytes();
string Disassemble();
string ListEncodings();
string PrintStats( );
Scrutinizer.IScrutinizer CreateScrutinizer( );
};
public interface IAMDDriver
{
IEnumerable Asics { get; }
///
/// Compile a DX shader blob and return the
///
///
///
IAMDShader CompileDXBlob(IAMDAsic asic, byte[] blob, IDXShaderReflection reflect );
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Configuration/AssemblyInfo.cs
================================================
//
//
//
//
// $Revision: 1618 $
//
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: CLSCompliant(true)]
[assembly: StringFreezing()]
[assembly: AssemblyTitle("ICSharpCode.TextEditor")]
[assembly: AssemblyDescription("A .NET text editor control")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
================================================
FILE: src/ICSharpCode.TextEditor/Project/GlobalAssemblyInfo.cs
================================================
//
//
//
//
// $Revision: 1040 $
//
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
// //
// DO NOT EDIT GlobalAssemblyInfo.cs, it is recreated using AssemblyInfo.template whenever //
// StartUp is compiled. //
// //
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
using System.Reflection;
[assembly: System.Runtime.InteropServices.ComVisible(false)]
[assembly: AssemblyCompany("ic#code")]
[assembly: AssemblyProduct("SharpDevelop")]
[assembly: AssemblyCopyright("2000-2008 AlphaSierraPapa")]
[assembly: AssemblyVersion(RevisionClass.FullVersion)]
internal static class RevisionClass
{
public const string Major = "3";
public const string Minor = "0";
public const string Build = "0";
public const string Revision = "3437";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/ICSharpCode.TextEditor.csproj
================================================
DebugAnyCPU9.0.210222.0{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}ICSharpCode.TextEditorLibrary4FalseFalseOnSuccessfulBuildLibrarytrueResources\ICSharpCode.TextEditor.snkICSharpCode.TextEditorFalseAuto98041856AnyCPU4096v4.03.5FalseFalseTruebin\Debug\TRACE;DEBUGfalse-Microsoft.Design#CA1012;-Microsoft.Design#CA2210;-Microsoft.Design#CA1040;-Microsoft.Design#CA1005;-Microsoft.Design#CA1020;-Microsoft.Design#CA1021;-Microsoft.Design#CA1010;-Microsoft.Design#CA1011;-Microsoft.Design#CA1009;-Microsoft.Design#CA1050;-Microsoft.Design#CA1026;-Microsoft.Design#CA1019;-Microsoft.Design#CA1031;-Microsoft.Design#CA1047;-Microsoft.Design#CA1000;-Microsoft.Design#CA1048;-Microsoft.Design#CA1051;-Microsoft.Design#CA1002;-Microsoft.Design#CA1061;-Microsoft.Design#CA1006;-Microsoft.Design#CA1046;-Microsoft.Design#CA1045;-Microsoft.Design#CA1038;-Microsoft.Design#CA1008;-Microsoft.Design#CA1028;-Microsoft.Design#CA1004;-Microsoft.Design#CA1035;-Microsoft.Design#CA1063;-Microsoft.Design#CA1032;-Microsoft.Design#CA1023;-Microsoft.Design#CA1033;-Microsoft.Design#CA1039;-Microsoft.Design#CA1016;-Microsoft.Design#CA1014;-Microsoft.Design#CA1017;-Microsoft.Design#CA1018;-Microsoft.Design#CA1027;-Microsoft.Design#CA1059;-Microsoft.Design#CA1060;-Microsoft.Design#CA1034;-Microsoft.Design#CA1013;-Microsoft.Design#CA1036;-Microsoft.Design#CA1044;-Microsoft.Design#CA1041;-Microsoft.Design#CA1025;-Microsoft.Design#CA1052;-Microsoft.Design#CA1053;-Microsoft.Design#CA1057;-Microsoft.Design#CA1058;-Microsoft.Design#CA1001;-Microsoft.Design#CA1049;-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055;-Microsoft.Design#CA1030;-Microsoft.Design#CA1003;-Microsoft.Design#CA1007;-Microsoft.Design#CA1043;-Microsoft.Design#CA1024;-Microsoft.Design#CA1062;-Microsoft.Globalization#CA1301;-Microsoft.Globalization#CA1302;-Microsoft.Globalization#CA1303;-Microsoft.Globalization#CA1306;-Microsoft.Globalization#CA1304;-Microsoft.Globalization#CA1305;-Microsoft.Globalization#CA1300;-Microsoft.Mobility#CA1600;-Microsoft.Mobility#CA1601;-Microsoft.Naming#CA1718;-Microsoft.Naming#CA1720;-Microsoft.Naming#CA1700;-Microsoft.Naming#CA1712;-Microsoft.Naming#CA1713;-Microsoft.Naming#CA1709;-Microsoft.Naming#CA1708;-Microsoft.Naming#CA1715;-Microsoft.Naming#CA1710;-Microsoft.Naming#CA1707;-Microsoft.Naming#CA1722;-Microsoft.Naming#CA1711;-Microsoft.Naming#CA1716;-Microsoft.Naming#CA1705;-Microsoft.Naming#CA1725;-Microsoft.Naming#CA1719;-Microsoft.Naming#CA1721;-Microsoft.Naming#CA1706;-Microsoft.Naming#CA1724;-Microsoft.Naming#CA1726;-Microsoft.Performance#CA1809;-Microsoft.Performance#CA1811;-Microsoft.Performance#CA1812;-Microsoft.Performance#CA1807;-Microsoft.Performance#CA1813;-Microsoft.Performance#CA1823;-Microsoft.Performance#CA1816;-Microsoft.Performance#CA1817;-Microsoft.Performance#CA1800;-Microsoft.Performance#CA1818;-Microsoft.Performance#CA1805;-Microsoft.Performance#CA1810;-Microsoft.Performance#CA1822;-Microsoft.Performance#CA1815;-Microsoft.Performance#CA1814;-Microsoft.Performance#CA1819;-Microsoft.Performance#CA1804;-Microsoft.Performance#CA1820;-Microsoft.Performance#CA1802;-Microsoft.Security#CA2116;-Microsoft.Security#CA2117;-Microsoft.Security#CA2105;-Microsoft.Security#CA2115;-Microsoft.Security#CA2104;-Microsoft.Security#CA2122;-Microsoft.Security#CA2114;-Microsoft.Security#CA2123;-Microsoft.Security#CA2111;-Microsoft.Security#CA2108;-Microsoft.Security#CA2107;-Microsoft.Security#CA2103;-Microsoft.Security#CA2100;-Microsoft.Security#CA2118;-Microsoft.Security#CA2109;-Microsoft.Security#CA2119;-Microsoft.Security#CA2106;-Microsoft.Security#CA2112;-Microsoft.Security#CA2110;-Microsoft.Security#CA2120;-Microsoft.Security#CA2101;-Microsoft.Security#CA2121;-Microsoft.Security#CA2126;-Microsoft.Security#CA2124;-Microsoft.Usage#CA2209;-Microsoft.Usage#CA2236;-Microsoft.Usage#CA2227;-Microsoft.Usage#CA2213;-Microsoft.Usage#CA2216;-Microsoft.Usage#CA2215;-Microsoft.Usage#CA2214;-Microsoft.Usage#CA2222;-Microsoft.Usage#CA2202;-Microsoft.Usage#CA1806;-Microsoft.Usage#CA2217;-Microsoft.Usage#CA2212;-Microsoft.Usage#CA2219;-Microsoft.Usage#CA2201;-Microsoft.Usage#CA2228;-Microsoft.Usage#CA2221;-Microsoft.Usage#CA2220;-Microsoft.Usage#CA2240;-Microsoft.Usage#CA2229;-Microsoft.Usage#CA2238;-Microsoft.Usage#CA2207;-Microsoft.Usage#CA2208;-Microsoft.Usage#CA2235;-Microsoft.Usage#CA2237;-Microsoft.Usage#CA2232;-Microsoft.Usage#CA2223;-Microsoft.Usage#CA2211;-Microsoft.Usage#CA2233;-Microsoft.Usage#CA2225;-Microsoft.Usage#CA2226;-Microsoft.Usage#CA2231;-Microsoft.Usage#CA2224;-Microsoft.Usage#CA2218;-Microsoft.Usage#CA2234;-Microsoft.Usage#CA2241;-Microsoft.Usage#CA2239;-Microsoft.Usage#CA2200;-Microsoft.Usage#CA1801;-Microsoft.Usage#CA2205;-Microsoft.Usage#CA22302trueFalseFalsebin\Release\FalseTRACEFulltrueNoneFalseFormFindAndReplaceForm.csFormFormFormComponentUserControlUserControlComponentFormUserControlComponentDesignerFindAndReplaceForm.csrem ..\src\Tools\UpdateAssemblyInfo\bin\Debug\UpdateAssemblyInfo.execopy $(TargetPath) $(SolutionDir)\..\bin
================================================
FILE: src/ICSharpCode.TextEditor/Project/Resources/CPP-Mode.xshd
================================================
~!%^*()-+=|\#/{}[]:;"'<> , .?#///**/""''(
================================================
FILE: src/ICSharpCode.TextEditor/Project/Resources/GLSL-Mode.xshd
================================================
~!%^*()-+=|\#/{}[]:;"'<> , .?#///**/""''(
================================================
FILE: src/ICSharpCode.TextEditor/Project/Resources/HLSL-Mode.xshd
================================================
~!%^*()-+=|\#/{}[]:;"'<> , .?#///**/""''(
================================================
FILE: src/ICSharpCode.TextEditor/Project/Resources/Mode.xsd
================================================
This schema defines the syntax for mode definitions in SharpDevelop.
The schema can be simplified quite a bit but it does the job as is.
If you are using this file as a reference it is probably easiest to scroll to
the botton to find the definition of the root element called SyntaxDefinition and
then unwind the different type definitions and refernces.
Note on coloring:
Many tags define how some symbol should be colored. If a specific symbol
can not be matched onto either a Span definition, Keyword, or a Digit/Number it
will be rendered in the current default color. Which is the default color of the
current span or the default color of the mode as a whole if no span has been entered.
================================================
FILE: src/ICSharpCode.TextEditor/Project/Resources/SyntaxModes.xml
================================================
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Actions/BookmarkActions.cs
================================================
//
//
//
//
// $Revision: 3272 $
//
using System;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class ToggleBookmark : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.Document.BookmarkManager.ToggleMarkAt(textArea.Caret.Position);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, textArea.Caret.Line));
textArea.Document.CommitUpdate();
}
}
public class GotoPrevBookmark : AbstractEditAction
{
Predicate predicate = null;
public GotoPrevBookmark(Predicate predicate)
{
this.predicate = predicate;
}
public override void Execute(TextArea textArea)
{
Bookmark mark = textArea.Document.BookmarkManager.GetPrevMark(textArea.Caret.Line, predicate);
if (mark != null) {
textArea.Caret.Position = mark.Location;
textArea.SelectionManager.ClearSelection();
textArea.SetDesiredColumn();
}
}
}
public class GotoNextBookmark : AbstractEditAction
{
Predicate predicate = null;
public GotoNextBookmark(Predicate predicate)
{
this.predicate = predicate;
}
public override void Execute(TextArea textArea)
{
Bookmark mark = textArea.Document.BookmarkManager.GetNextMark(textArea.Caret.Line, predicate);
if (mark != null) {
textArea.Caret.Position = mark.Location;
textArea.SelectionManager.ClearSelection();
textArea.SetDesiredColumn();
}
}
}
public class ClearAllBookmarks : AbstractEditAction
{
Predicate predicate = null;
public ClearAllBookmarks(Predicate predicate)
{
this.predicate = predicate;
}
public override void Execute(TextArea textArea)
{
textArea.Document.BookmarkManager.RemoveMarks(predicate);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
textArea.Document.CommitUpdate();
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Actions/CaretActions.cs
================================================
//
//
//
//
// $Revision: 2681 $
//
using System;
using System.Collections.Generic;
using System.Drawing;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class CaretLeft : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
TextLocation position = textArea.Caret.Position;
List foldings = textArea.Document.FoldingManager.GetFoldedFoldingsWithEnd(position.Y);
FoldMarker justBeforeCaret = null;
foreach (FoldMarker fm in foldings) {
if (fm.EndColumn == position.X) {
justBeforeCaret = fm;
break; // the first folding found is the folding with the smallest Startposition
}
}
if (justBeforeCaret != null) {
position.Y = justBeforeCaret.StartLine;
position.X = justBeforeCaret.StartColumn;
} else {
if (position.X > 0) {
--position.X;
} else if (position.Y > 0) {
LineSegment lineAbove = textArea.Document.GetLineSegment(position.Y - 1);
position = new TextLocation(lineAbove.Length, position.Y - 1);
}
}
textArea.Caret.Position = position;
textArea.SetDesiredColumn();
}
}
public class CaretRight : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
LineSegment curLine = textArea.Document.GetLineSegment(textArea.Caret.Line);
TextLocation position = textArea.Caret.Position;
List foldings = textArea.Document.FoldingManager.GetFoldedFoldingsWithStart(position.Y);
FoldMarker justBehindCaret = null;
foreach (FoldMarker fm in foldings) {
if (fm.StartColumn == position.X) {
justBehindCaret = fm;
break;
}
}
if (justBehindCaret != null) {
position.Y = justBehindCaret.EndLine;
position.X = justBehindCaret.EndColumn;
} else { // no folding is interesting
if (position.X < curLine.Length || textArea.TextEditorProperties.AllowCaretBeyondEOL) {
++position.X;
} else if (position.Y + 1 < textArea.Document.TotalNumberOfLines) {
++position.Y;
position.X = 0;
}
}
textArea.Caret.Position = position;
textArea.SetDesiredColumn();
}
}
public class CaretUp : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
TextLocation position = textArea.Caret.Position;
int lineNr = position.Y;
int visualLine = textArea.Document.GetVisibleLine(lineNr);
if (visualLine > 0) {
Point pos = new Point(textArea.TextView.GetDrawingXPos(lineNr, position.X),
textArea.TextView.DrawingPosition.Y + (visualLine - 1) * textArea.TextView.FontHeight - textArea.TextView.TextArea.VirtualTop.Y);
textArea.Caret.Position = textArea.TextView.GetLogicalPosition(pos);
textArea.SetCaretToDesiredColumn();
}
// if (textArea.Caret.Line > 0) {
// textArea.SetCaretToDesiredColumn(textArea.Caret.Line - 1);
// }
}
}
public class CaretDown : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
TextLocation position = textArea.Caret.Position;
int lineNr = position.Y;
int visualLine = textArea.Document.GetVisibleLine(lineNr);
if (visualLine < textArea.Document.GetVisibleLine(textArea.Document.TotalNumberOfLines)) {
Point pos = new Point(textArea.TextView.GetDrawingXPos(lineNr, position.X),
textArea.TextView.DrawingPosition.Y
+ (visualLine + 1) * textArea.TextView.FontHeight
- textArea.TextView.TextArea.VirtualTop.Y);
textArea.Caret.Position = textArea.TextView.GetLogicalPosition(pos);
textArea.SetCaretToDesiredColumn();
}
// if (textArea.Caret.Line + 1 < textArea.Document.TotalNumberOfLines) {
// textArea.SetCaretToDesiredColumn(textArea.Caret.Line + 1);
// }
}
}
public class WordRight : CaretRight
{
public override void Execute(TextArea textArea)
{
LineSegment line = textArea.Document.GetLineSegment(textArea.Caret.Position.Y);
TextLocation oldPos = textArea.Caret.Position;
TextLocation newPos;
if (textArea.Caret.Column >= line.Length) {
newPos = new TextLocation(0, textArea.Caret.Line + 1);
} else {
int nextWordStart = TextUtilities.FindNextWordStart(textArea.Document, textArea.Caret.Offset);
newPos = textArea.Document.OffsetToPosition(nextWordStart);
}
// handle fold markers
List foldings = textArea.Document.FoldingManager.GetFoldingsFromPosition(newPos.Y, newPos.X);
foreach (FoldMarker marker in foldings) {
if (marker.IsFolded) {
if (oldPos.X == marker.StartColumn && oldPos.Y == marker.StartLine) {
newPos = new TextLocation(marker.EndColumn, marker.EndLine);
} else {
newPos = new TextLocation(marker.StartColumn, marker.StartLine);
}
break;
}
}
textArea.Caret.Position = newPos;
textArea.SetDesiredColumn();
}
}
public class WordLeft : CaretLeft
{
public override void Execute(TextArea textArea)
{
TextLocation oldPos = textArea.Caret.Position;
if (textArea.Caret.Column == 0) {
base.Execute(textArea);
} else {
LineSegment line = textArea.Document.GetLineSegment(textArea.Caret.Position.Y);
int prevWordStart = TextUtilities.FindPrevWordStart(textArea.Document, textArea.Caret.Offset);
TextLocation newPos = textArea.Document.OffsetToPosition(prevWordStart);
// handle fold markers
List foldings = textArea.Document.FoldingManager.GetFoldingsFromPosition(newPos.Y, newPos.X);
foreach (FoldMarker marker in foldings) {
if (marker.IsFolded) {
if (oldPos.X == marker.EndColumn && oldPos.Y == marker.EndLine) {
newPos = new TextLocation(marker.StartColumn, marker.StartLine);
} else {
newPos = new TextLocation(marker.EndColumn, marker.EndLine);
}
break;
}
}
textArea.Caret.Position = newPos;
textArea.SetDesiredColumn();
}
}
}
public class ScrollLineUp : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.AutoClearSelection = false;
textArea.MotherTextAreaControl.VScrollBar.Value = Math.Max(textArea.MotherTextAreaControl.VScrollBar.Minimum,
textArea.VirtualTop.Y - textArea.TextView.FontHeight);
}
}
public class ScrollLineDown : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.AutoClearSelection = false;
textArea.MotherTextAreaControl.VScrollBar.Value = Math.Min(textArea.MotherTextAreaControl.VScrollBar.Maximum,
textArea.VirtualTop.Y + textArea.TextView.FontHeight);
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Actions/ClipBoardActions.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
namespace ICSharpCode.TextEditor.Actions
{
public class Cut : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
textArea.ClipboardHandler.Cut(null, null);
}
}
public class Copy : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.AutoClearSelection = false;
textArea.ClipboardHandler.Copy(null, null);
}
}
public class Paste : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
textArea.ClipboardHandler.Paste(null, null);
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Actions/FindReplaceAction.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ICSharpCode.TextEditor.Actions
{
public class FindReplaceAction : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
ICSharpCode.TextEditor.FindAndReplaceForm frm = new FindAndReplaceForm();
frm.ShowFor(textArea.MotherTextEditorControl, false);
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Actions/FoldActions.cs
================================================
//
//
//
//
// $Revision: 2972 $
//
using System;
using System.Collections.Generic;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class ToggleFolding : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
List foldMarkers = textArea.Document.FoldingManager.GetFoldingsWithStart(textArea.Caret.Line);
if (foldMarkers.Count != 0) {
foreach (FoldMarker fm in foldMarkers)
fm.IsFolded = !fm.IsFolded;
} else {
foldMarkers = textArea.Document.FoldingManager.GetFoldingsContainsLineNumber(textArea.Caret.Line);
if (foldMarkers.Count != 0) {
FoldMarker innerMost = foldMarkers[0];
for (int i = 1; i < foldMarkers.Count; i++) {
if (new TextLocation(foldMarkers[i].StartColumn, foldMarkers[i].StartLine) >
new TextLocation(innerMost.StartColumn, innerMost.StartLine))
{
innerMost = foldMarkers[i];
}
}
innerMost.IsFolded = !innerMost.IsFolded;
}
}
textArea.Document.FoldingManager.NotifyFoldingsChanged(EventArgs.Empty);
}
}
public class ToggleAllFoldings : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
bool doFold = true;
foreach (FoldMarker fm in textArea.Document.FoldingManager.FoldMarker) {
if (fm.IsFolded) {
doFold = false;
break;
}
}
foreach (FoldMarker fm in textArea.Document.FoldingManager.FoldMarker) {
fm.IsFolded = doFold;
}
textArea.Document.FoldingManager.NotifyFoldingsChanged(EventArgs.Empty);
}
}
public class ShowDefinitionsOnly : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
foreach (FoldMarker fm in textArea.Document.FoldingManager.FoldMarker) {
fm.IsFolded = fm.FoldType == FoldType.MemberBody || fm.FoldType == FoldType.Region;
}
textArea.Document.FoldingManager.NotifyFoldingsChanged(EventArgs.Empty);
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Actions/FormatActions.cs
================================================
//
//
//
//
// $Revision: 2640 $
//
using System;
using System.Text;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public abstract class AbstractLineFormatAction : AbstractEditAction
{
protected TextArea textArea;
abstract protected void Convert(IDocument document, int startLine, int endLine);
public override void Execute(TextArea textArea)
{
this.textArea = textArea;
textArea.BeginUpdate();
textArea.Document.UndoStack.StartUndoGroup();
if (textArea.SelectionManager.HasSomethingSelected) {
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
Convert(textArea.Document, selection.StartPosition.Y, selection.EndPosition.Y);
}
} else {
Convert(textArea.Document, 0, textArea.Document.TotalNumberOfLines - 1);
}
textArea.Document.UndoStack.EndUndoGroup();
textArea.Caret.ValidateCaretPos();
textArea.EndUpdate();
textArea.Refresh();
}
}
public abstract class AbstractSelectionFormatAction : AbstractEditAction
{
protected TextArea textArea;
abstract protected void Convert(IDocument document, int offset, int length);
public override void Execute(TextArea textArea)
{
this.textArea = textArea;
textArea.BeginUpdate();
if (textArea.SelectionManager.HasSomethingSelected) {
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
Convert(textArea.Document, selection.Offset, selection.Length);
}
} else {
Convert(textArea.Document, 0, textArea.Document.TextLength);
}
textArea.Caret.ValidateCaretPos();
textArea.EndUpdate();
textArea.Refresh();
}
}
public class RemoveLeadingWS : AbstractLineFormatAction
{
protected override void Convert(IDocument document, int y1, int y2)
{
for (int i = y1; i < y2; ++i) {
LineSegment line = document.GetLineSegment(i);
int removeNumber = 0;
for (int x = line.Offset; x < line.Offset + line.Length && Char.IsWhiteSpace(document.GetCharAt(x)); ++x) {
++removeNumber;
}
if (removeNumber > 0) {
document.Remove(line.Offset, removeNumber);
}
}
}
}
public class RemoveTrailingWS : AbstractLineFormatAction
{
protected override void Convert(IDocument document, int y1, int y2)
{
for (int i = y2 - 1; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
int removeNumber = 0;
for (int x = line.Offset + line.Length - 1; x >= line.Offset && Char.IsWhiteSpace(document.GetCharAt(x)); --x) {
++removeNumber;
}
if (removeNumber > 0) {
document.Remove(line.Offset + line.Length - removeNumber, removeNumber);
}
}
}
}
public class ToUpperCase : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
string what = document.GetText(startOffset, length).ToUpper();
document.Replace(startOffset, length, what);
}
}
public class ToLowerCase : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
string what = document.GetText(startOffset, length).ToLower();
document.Replace(startOffset, length, what);
}
}
public class InvertCaseAction : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
StringBuilder what = new StringBuilder(document.GetText(startOffset, length));
for (int i = 0; i < what.Length; ++i) {
what[i] = Char.IsUpper(what[i]) ? Char.ToLower(what[i]) : Char.ToUpper(what[i]);
}
document.Replace(startOffset, length, what.ToString());
}
}
public class CapitalizeAction : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
StringBuilder what = new StringBuilder(document.GetText(startOffset, length));
for (int i = 0; i < what.Length; ++i) {
if (!Char.IsLetter(what[i]) && i < what.Length - 1) {
what[i + 1] = Char.ToUpper(what[i + 1]);
}
}
document.Replace(startOffset, length, what.ToString());
}
}
public class ConvertTabsToSpaces : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
string what = document.GetText(startOffset, length);
string spaces = new string(' ', document.TextEditorProperties.TabIndent);
document.Replace(startOffset, length, what.Replace("\t", spaces));
}
}
public class ConvertSpacesToTabs : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
string what = document.GetText(startOffset, length);
string spaces = new string(' ', document.TextEditorProperties.TabIndent);
document.Replace(startOffset, length, what.Replace(spaces, "\t"));
}
}
public class ConvertLeadingTabsToSpaces : AbstractLineFormatAction
{
protected override void Convert(IDocument document, int y1, int y2)
{
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if(line.Length > 0) {
// count how many whitespace characters there are at the start
int whiteSpace = 0;
for(whiteSpace = 0; whiteSpace < line.Length && Char.IsWhiteSpace(document.GetCharAt(line.Offset + whiteSpace)); whiteSpace++) {
// deliberately empty
}
if(whiteSpace > 0) {
string newLine = document.GetText(line.Offset,whiteSpace);
string newPrefix = newLine.Replace("\t",new string(' ', document.TextEditorProperties.TabIndent));
document.Replace(line.Offset,whiteSpace,newPrefix);
}
}
}
}
}
public class ConvertLeadingSpacesToTabs : AbstractLineFormatAction
{
protected override void Convert(IDocument document, int y1, int y2)
{
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if(line.Length > 0) {
// note: some users may prefer a more radical ConvertLeadingSpacesToTabs that
// means there can be no spaces before the first character even if the spaces
// didn't add up to a whole number of tabs
string newLine = TextUtilities.LeadingWhiteSpaceToTabs(document.GetText(line.Offset,line.Length), document.TextEditorProperties.TabIndent);
document.Replace(line.Offset,line.Length,newLine);
}
}
}
}
///
/// This is a sample editaction plugin, it indents the selected area.
///
public class FormatBuffer : AbstractLineFormatAction
{
protected override void Convert(IDocument document, int startLine, int endLine)
{
document.FormattingStrategy.IndentLines(textArea, startLine, endLine);
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Actions/HomeEndActions.cs
================================================
//
//
//
//
// $Revision: 2659 $
//
using System;
using System.Collections.Generic;
using System.Drawing;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class Home : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
LineSegment curLine;
TextLocation newPos = textArea.Caret.Position;
bool jumpedIntoFolding = false;
do {
curLine = textArea.Document.GetLineSegment(newPos.Y);
if (TextUtilities.IsEmptyLine(textArea.Document, newPos.Y)) {
if (newPos.X != 0) {
newPos.X = 0;
} else {
newPos.X = curLine.Length;
}
} else {
int firstCharOffset = TextUtilities.GetFirstNonWSChar(textArea.Document, curLine.Offset);
int firstCharColumn = firstCharOffset - curLine.Offset;
if (newPos.X == firstCharColumn) {
newPos.X = 0;
} else {
newPos.X = firstCharColumn;
}
}
List foldings = textArea.Document.FoldingManager.GetFoldingsFromPosition(newPos.Y, newPos.X);
jumpedIntoFolding = false;
foreach (FoldMarker foldMarker in foldings) {
if (foldMarker.IsFolded) {
newPos = new TextLocation(foldMarker.StartColumn, foldMarker.StartLine);
jumpedIntoFolding = true;
break;
}
}
} while (jumpedIntoFolding);
if (newPos != textArea.Caret.Position) {
textArea.Caret.Position = newPos;
textArea.SetDesiredColumn();
}
}
}
public class End : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
LineSegment curLine;
TextLocation newPos = textArea.Caret.Position;
bool jumpedIntoFolding = false;
do {
curLine = textArea.Document.GetLineSegment(newPos.Y);
newPos.X = curLine.Length;
List foldings = textArea.Document.FoldingManager.GetFoldingsFromPosition(newPos.Y, newPos.X);
jumpedIntoFolding = false;
foreach (FoldMarker foldMarker in foldings) {
if (foldMarker.IsFolded) {
newPos = new TextLocation(foldMarker.EndColumn, foldMarker.EndLine);
jumpedIntoFolding = true;
break;
}
}
} while (jumpedIntoFolding);
if (newPos != textArea.Caret.Position) {
textArea.Caret.Position = newPos;
textArea.SetDesiredColumn();
}
}
}
public class MoveToStart : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
if (textArea.Caret.Line != 0 || textArea.Caret.Column != 0) {
textArea.Caret.Position = new TextLocation(0, 0);
textArea.SetDesiredColumn();
}
}
}
public class MoveToEnd : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
TextLocation endPos = textArea.Document.OffsetToPosition(textArea.Document.TextLength);
if (textArea.Caret.Position != endPos) {
textArea.Caret.Position = endPos;
textArea.SetDesiredColumn();
}
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Actions/IEditAction.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
using System.Windows.Forms;
namespace ICSharpCode.TextEditor.Actions
{
///
/// To define a new key for the textarea, you must write a class which
/// implements this interface.
///
public interface IEditAction
{
///
/// An array of keys on which this edit action occurs.
///
Keys[] Keys {
get;
set;
}
///
/// When the key which is defined per XML is pressed, this method will be launched.
///
void Execute(TextArea textArea);
}
///
/// To define a new key for the textarea, you must write a class which
/// implements this interface.
///
public abstract class AbstractEditAction : IEditAction
{
Keys[] keys = null;
///
/// An array of keys on which this edit action occurs.
///
public Keys[] Keys {
get {
return keys;
}
set {
keys = value;
}
}
///
/// When the key which is defined per XML is pressed, this method will be launched.
///
public abstract void Execute(TextArea textArea);
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Actions/MiscActions.cs
================================================
//
//
//
//
// $Revision: 3205 $
//
using System;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class Tab : AbstractEditAction
{
public static string GetIndentationString(IDocument document)
{
return GetIndentationString(document, null);
}
public static string GetIndentationString(IDocument document, TextArea textArea)
{
StringBuilder indent = new StringBuilder();
if (document.TextEditorProperties.ConvertTabsToSpaces) {
int tabIndent = document.TextEditorProperties.IndentationSize;
if (textArea != null) {
int column = textArea.TextView.GetVisualColumn(textArea.Caret.Line, textArea.Caret.Column);
indent.Append(new String(' ', tabIndent - column % tabIndent));
} else {
indent.Append(new String(' ', tabIndent));
}
} else {
indent.Append('\t');
}
return indent.ToString();
}
void InsertTabs(IDocument document, ISelection selection, int y1, int y2)
{
string indentationString = GetIndentationString(document);
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if (i == y2 && i == selection.EndPosition.Y && selection.EndPosition.X == 0) {
continue;
}
// this bit is optional - but useful if you are using block tabbing to sort out
// a source file with a mixture of tabs and spaces
// string newLine = document.GetText(line.Offset,line.Length);
// document.Replace(line.Offset,line.Length,newLine);
document.Insert(line.Offset, indentationString);
}
}
void InsertTabAtCaretPosition(TextArea textArea)
{
switch (textArea.Caret.CaretMode) {
case CaretMode.InsertMode:
textArea.InsertString(GetIndentationString(textArea.Document, textArea));
break;
case CaretMode.OverwriteMode:
string indentStr = GetIndentationString(textArea.Document, textArea);
textArea.ReplaceChar(indentStr[0]);
if (indentStr.Length > 1) {
textArea.InsertString(indentStr.Substring(1));
}
break;
}
textArea.SetDesiredColumn();
}
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
textArea.Document.UndoStack.StartUndoGroup();
if (textArea.SelectionManager.HasSomethingSelected) {
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
int startLine = selection.StartPosition.Y;
int endLine = selection.EndPosition.Y;
if (startLine != endLine) {
textArea.BeginUpdate();
InsertTabs(textArea.Document, selection, startLine, endLine);
textArea.Document.UpdateQueue.Clear();
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.LinesBetween, startLine, endLine));
textArea.EndUpdate();
} else {
InsertTabAtCaretPosition(textArea);
break;
}
}
textArea.Document.CommitUpdate();
textArea.AutoClearSelection = false;
} else {
InsertTabAtCaretPosition(textArea);
}
textArea.Document.UndoStack.EndUndoGroup();
}
}
public class ShiftTab : AbstractEditAction
{
void RemoveTabs(IDocument document, ISelection selection, int y1, int y2)
{
document.UndoStack.StartUndoGroup();
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if (i == y2 && line.Offset == selection.EndOffset) {
continue;
}
if (line.Length > 0) {
/**** TextPad Strategy:
/// first convert leading whitespace to tabs (controversial! - not all editors work like this)
string newLine = TextUtilities.LeadingWhiteSpaceToTabs(document.GetText(line.Offset,line.Length),document.Properties.Get("TabIndent", 4));
if(newLine.Length > 0 && newLine[0] == '\t') {
document.Replace(line.Offset,line.Length,newLine.Substring(1));
++redocounter;
}
else if(newLine.Length > 0 && newLine[0] == ' ') {
/// there were just some leading spaces but less than TabIndent of them
int leadingSpaces = 1;
for(leadingSpaces = 1; leadingSpaces < newLine.Length && newLine[leadingSpaces] == ' '; leadingSpaces++) {
/// deliberately empty
}
document.Replace(line.Offset,line.Length,newLine.Substring(leadingSpaces));
++redocounter;
}
/// else
/// there were no leading tabs or spaces on this line so do nothing
/// MS Visual Studio 6 strategy:
****/
// string temp = document.GetText(line.Offset,line.Length);
if (line.Length > 0) {
int charactersToRemove = 0;
if(document.GetCharAt(line.Offset) == '\t') { // first character is a tab - just remove it
charactersToRemove = 1;
} else if(document.GetCharAt(line.Offset) == ' ') {
int leadingSpaces = 1;
int tabIndent = document.TextEditorProperties.IndentationSize;
for (leadingSpaces = 1; leadingSpaces < line.Length && document.GetCharAt(line.Offset + leadingSpaces) == ' '; leadingSpaces++) {
// deliberately empty
}
if(leadingSpaces >= tabIndent) {
// just remove tabIndent
charactersToRemove = tabIndent;
}
else if(line.Length > leadingSpaces && document.GetCharAt(line.Offset + leadingSpaces) == '\t') {
// remove the leading spaces and the following tab as they add up
// to just one tab stop
charactersToRemove = leadingSpaces+1;
}
else {
// just remove the leading spaces
charactersToRemove = leadingSpaces;
}
}
if (charactersToRemove > 0) {
document.Remove(line.Offset,charactersToRemove);
}
}
}
}
document.UndoStack.EndUndoGroup();
}
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
if (textArea.SelectionManager.HasSomethingSelected) {
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
int startLine = selection.StartPosition.Y;
int endLine = selection.EndPosition.Y;
textArea.BeginUpdate();
RemoveTabs(textArea.Document, selection, startLine, endLine);
textArea.Document.UpdateQueue.Clear();
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.LinesBetween, startLine, endLine));
textArea.EndUpdate();
}
textArea.AutoClearSelection = false;
} else {
// Pressing Shift-Tab with nothing selected the cursor will move back to the
// previous tab stop. It will stop at the beginning of the line. Also, the desired
// column is updated to that column.
LineSegment line = textArea.Document.GetLineSegmentForOffset(textArea.Caret.Offset);
string startOfLine = textArea.Document.GetText(line.Offset,textArea.Caret.Offset - line.Offset);
int tabIndent = textArea.Document.TextEditorProperties.IndentationSize;
int currentColumn = textArea.Caret.Column;
int remainder = currentColumn % tabIndent;
if (remainder == 0) {
textArea.Caret.DesiredColumn = Math.Max(0, currentColumn - tabIndent);
} else {
textArea.Caret.DesiredColumn = Math.Max(0, currentColumn - remainder);
}
textArea.SetCaretToDesiredColumn();
}
}
}
public class ToggleComment : AbstractEditAction
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
if (textArea.Document.HighlightingStrategy.Properties.ContainsKey("LineComment")) {
new ToggleLineComment().Execute(textArea);
} else if (textArea.Document.HighlightingStrategy.Properties.ContainsKey("BlockCommentBegin") &&
textArea.Document.HighlightingStrategy.Properties.ContainsKey("BlockCommentBegin")) {
new ToggleBlockComment().Execute(textArea);
}
}
}
public class ToggleLineComment : AbstractEditAction
{
int firstLine;
int lastLine;
void RemoveCommentAt(IDocument document, string comment, ISelection selection, int y1, int y2)
{
firstLine = y1;
lastLine = y2;
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if (selection != null && i == y2 && line.Offset == selection.Offset + selection.Length) {
--lastLine;
continue;
}
string lineText = document.GetText(line.Offset, line.Length);
if (lineText.Trim().StartsWith(comment)) {
document.Remove(line.Offset + lineText.IndexOf(comment), comment.Length);
}
}
}
void SetCommentAt(IDocument document, string comment, ISelection selection, int y1, int y2)
{
firstLine = y1;
lastLine = y2;
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if (selection != null && i == y2 && line.Offset == selection.Offset + selection.Length) {
--lastLine;
continue;
}
string lineText = document.GetText(line.Offset, line.Length);
document.Insert(line.Offset, comment);
}
}
bool ShouldComment(IDocument document, string comment, ISelection selection, int startLine, int endLine)
{
for (int i = endLine; i >= startLine; --i) {
LineSegment line = document.GetLineSegment(i);
if (selection != null && i == endLine && line.Offset == selection.Offset + selection.Length) {
--lastLine;
continue;
}
string lineText = document.GetText(line.Offset, line.Length);
if (!lineText.Trim().StartsWith(comment)) {
return true;
}
}
return false;
}
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
string comment = null;
if (textArea.Document.HighlightingStrategy.Properties.ContainsKey("LineComment")) {
comment = textArea.Document.HighlightingStrategy.Properties["LineComment"].ToString();
}
if (comment == null || comment.Length == 0) {
return;
}
textArea.Document.UndoStack.StartUndoGroup();
if (textArea.SelectionManager.HasSomethingSelected) {
bool shouldComment = true;
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
if (!ShouldComment(textArea.Document, comment, selection, selection.StartPosition.Y, selection.EndPosition.Y)) {
shouldComment = false;
break;
}
}
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
textArea.BeginUpdate();
if (shouldComment) {
SetCommentAt(textArea.Document, comment, selection, selection.StartPosition.Y, selection.EndPosition.Y);
} else {
RemoveCommentAt(textArea.Document, comment, selection, selection.StartPosition.Y, selection.EndPosition.Y);
}
textArea.Document.UpdateQueue.Clear();
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.LinesBetween, firstLine, lastLine));
textArea.EndUpdate();
}
textArea.Document.CommitUpdate();
textArea.AutoClearSelection = false;
} else {
textArea.BeginUpdate();
int caretLine = textArea.Caret.Line;
if (ShouldComment(textArea.Document, comment, null, caretLine, caretLine)) {
SetCommentAt(textArea.Document, comment, null, caretLine, caretLine);
} else {
RemoveCommentAt(textArea.Document, comment, null, caretLine, caretLine);
}
textArea.Document.UpdateQueue.Clear();
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, caretLine));
textArea.EndUpdate();
}
textArea.Document.UndoStack.EndUndoGroup();
}
}
public class ToggleBlockComment : AbstractEditAction
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
string commentStart = null;
if (textArea.Document.HighlightingStrategy.Properties.ContainsKey("BlockCommentBegin")) {
commentStart = textArea.Document.HighlightingStrategy.Properties["BlockCommentBegin"].ToString();
}
string commentEnd = null;
if (textArea.Document.HighlightingStrategy.Properties.ContainsKey("BlockCommentEnd")) {
commentEnd = textArea.Document.HighlightingStrategy.Properties["BlockCommentEnd"].ToString();
}
if (commentStart == null || commentStart.Length == 0 || commentEnd == null || commentEnd.Length == 0) {
return;
}
int selectionStartOffset;
int selectionEndOffset;
if (textArea.SelectionManager.HasSomethingSelected) {
selectionStartOffset = textArea.SelectionManager.SelectionCollection[0].Offset;
selectionEndOffset = textArea.SelectionManager.SelectionCollection[textArea.SelectionManager.SelectionCollection.Count - 1].EndOffset;
} else {
selectionStartOffset = textArea.Caret.Offset;
selectionEndOffset = selectionStartOffset;
}
BlockCommentRegion commentRegion = FindSelectedCommentRegion(textArea.Document, commentStart, commentEnd, selectionStartOffset, selectionEndOffset);
textArea.Document.UndoStack.StartUndoGroup();
if (commentRegion != null) {
RemoveComment(textArea.Document, commentRegion);
} else if (textArea.SelectionManager.HasSomethingSelected) {
SetCommentAt(textArea.Document, selectionStartOffset, selectionEndOffset, commentStart, commentEnd);
}
textArea.Document.UndoStack.EndUndoGroup();
textArea.Document.CommitUpdate();
textArea.AutoClearSelection = false;
}
public static BlockCommentRegion FindSelectedCommentRegion(IDocument document, string commentStart, string commentEnd, int selectionStartOffset, int selectionEndOffset)
{
if (document.TextLength == 0) {
return null;
}
// Find start of comment in selected text.
int commentEndOffset = -1;
string selectedText = document.GetText(selectionStartOffset, selectionEndOffset - selectionStartOffset);
int commentStartOffset = selectedText.IndexOf(commentStart);
if (commentStartOffset >= 0) {
commentStartOffset += selectionStartOffset;
}
// Find end of comment in selected text.
if (commentStartOffset >= 0) {
commentEndOffset = selectedText.IndexOf(commentEnd, commentStartOffset + commentStart.Length - selectionStartOffset);
} else {
commentEndOffset = selectedText.IndexOf(commentEnd);
}
if (commentEndOffset >= 0) {
commentEndOffset += selectionStartOffset;
}
// Find start of comment before or partially inside the
// selected text.
int commentEndBeforeStartOffset = -1;
if (commentStartOffset == -1) {
int offset = selectionEndOffset + commentStart.Length - 1;
if (offset > document.TextLength) {
offset = document.TextLength;
}
string text = document.GetText(0, offset);
commentStartOffset = text.LastIndexOf(commentStart);
if (commentStartOffset >= 0) {
// Find end of comment before comment start.
commentEndBeforeStartOffset = text.IndexOf(commentEnd, commentStartOffset, selectionStartOffset - commentStartOffset);
if (commentEndBeforeStartOffset > commentStartOffset) {
commentStartOffset = -1;
}
}
}
// Find end of comment after or partially after the
// selected text.
if (commentEndOffset == -1) {
int offset = selectionStartOffset + 1 - commentEnd.Length;
if (offset < 0) {
offset = selectionStartOffset;
}
string text = document.GetText(offset, document.TextLength - offset);
commentEndOffset = text.IndexOf(commentEnd);
if (commentEndOffset >= 0) {
commentEndOffset += offset;
}
}
if (commentStartOffset != -1 && commentEndOffset != -1) {
return new BlockCommentRegion(commentStart, commentEnd, commentStartOffset, commentEndOffset);
}
return null;
}
void SetCommentAt(IDocument document, int offsetStart, int offsetEnd, string commentStart, string commentEnd)
{
document.Insert(offsetEnd, commentEnd);
document.Insert(offsetStart, commentStart);
}
void RemoveComment(IDocument document, BlockCommentRegion commentRegion)
{
document.Remove(commentRegion.EndOffset, commentRegion.CommentEnd.Length);
document.Remove(commentRegion.StartOffset, commentRegion.CommentStart.Length);
}
}
public class BlockCommentRegion
{
string commentStart = String.Empty;
string commentEnd = String.Empty;
int startOffset = -1;
int endOffset = -1;
///
/// The end offset is the offset where the comment end string starts from.
///
public BlockCommentRegion(string commentStart, string commentEnd, int startOffset, int endOffset)
{
this.commentStart = commentStart;
this.commentEnd = commentEnd;
this.startOffset = startOffset;
this.endOffset = endOffset;
}
public string CommentStart {
get {
return commentStart;
}
}
public string CommentEnd {
get {
return commentEnd;
}
}
public int StartOffset {
get {
return startOffset;
}
}
public int EndOffset {
get {
return endOffset;
}
}
public override int GetHashCode()
{
int hashCode = 0;
unchecked {
if (commentStart != null) hashCode += 1000000007 * commentStart.GetHashCode();
if (commentEnd != null) hashCode += 1000000009 * commentEnd.GetHashCode();
hashCode += 1000000021 * startOffset.GetHashCode();
hashCode += 1000000033 * endOffset.GetHashCode();
}
return hashCode;
}
public override bool Equals(object obj)
{
BlockCommentRegion other = obj as BlockCommentRegion;
if (other == null) return false;
return this.commentStart == other.commentStart && this.commentEnd == other.commentEnd && this.startOffset == other.startOffset && this.endOffset == other.endOffset;
}
}
public class IndentSelection : AbstractEditAction
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
textArea.BeginUpdate();
if (textArea.SelectionManager.HasSomethingSelected) {
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
textArea.Document.FormattingStrategy.IndentLines(textArea, selection.StartPosition.Y, selection.EndPosition.Y);
}
} else {
textArea.Document.FormattingStrategy.IndentLines(textArea, 0, textArea.Document.TotalNumberOfLines - 1);
}
textArea.EndUpdate();
textArea.Refresh();
}
}
public class Backspace : AbstractEditAction
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
if (textArea.SelectionManager.HasSomethingSelected) {
Delete.DeleteSelection(textArea);
} else {
if (textArea.Caret.Offset > 0 && !textArea.IsReadOnly(textArea.Caret.Offset - 1)) {
textArea.BeginUpdate();
int curLineNr = textArea.Document.GetLineNumberForOffset(textArea.Caret.Offset);
int curLineOffset = textArea.Document.GetLineSegment(curLineNr).Offset;
if (curLineOffset == textArea.Caret.Offset) {
LineSegment line = textArea.Document.GetLineSegment(curLineNr - 1);
bool lastLine = curLineNr == textArea.Document.TotalNumberOfLines;
int lineEndOffset = line.Offset + line.Length;
int lineLength = line.Length;
textArea.Document.Remove(lineEndOffset, curLineOffset - lineEndOffset);
textArea.Caret.Position = new TextLocation(lineLength, curLineNr - 1);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, curLineNr - 1)));
} else {
int caretOffset = textArea.Caret.Offset - 1;
textArea.Caret.Position = textArea.Document.OffsetToPosition(caretOffset);
textArea.Document.Remove(caretOffset, 1);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToLineEnd, new TextLocation(textArea.Caret.Offset - textArea.Document.GetLineSegment(curLineNr).Offset, curLineNr)));
}
textArea.EndUpdate();
}
}
}
}
public class Delete : AbstractEditAction
{
internal static void DeleteSelection(TextArea textArea)
{
Debug.Assert(textArea.SelectionManager.HasSomethingSelected);
if (textArea.SelectionManager.SelectionIsReadonly)
return;
textArea.BeginUpdate();
textArea.Caret.Position = textArea.SelectionManager.SelectionCollection[0].StartPosition;
textArea.SelectionManager.RemoveSelectedText();
textArea.ScrollToCaret();
textArea.EndUpdate();
}
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
if (textArea.SelectionManager.HasSomethingSelected) {
DeleteSelection(textArea);
} else {
if (textArea.IsReadOnly(textArea.Caret.Offset))
return;
if (textArea.Caret.Offset < textArea.Document.TextLength) {
textArea.BeginUpdate();
int curLineNr = textArea.Document.GetLineNumberForOffset(textArea.Caret.Offset);
LineSegment curLine = textArea.Document.GetLineSegment(curLineNr);
if (curLine.Offset + curLine.Length == textArea.Caret.Offset) {
if (curLineNr + 1 < textArea.Document.TotalNumberOfLines) {
LineSegment nextLine = textArea.Document.GetLineSegment(curLineNr + 1);
textArea.Document.Remove(textArea.Caret.Offset, nextLine.Offset - textArea.Caret.Offset);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, curLineNr)));
}
} else {
textArea.Document.Remove(textArea.Caret.Offset, 1);
// textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToLineEnd, new TextLocation(textArea.Caret.Offset - textArea.Document.GetLineSegment(curLineNr).Offset, curLineNr)));
}
textArea.UpdateMatchingBracket();
textArea.EndUpdate();
}
}
}
}
public class MovePageDown : AbstractEditAction
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
int curLineNr = textArea.Caret.Line;
int requestedLineNumber = Math.Min(textArea.Document.GetNextVisibleLineAbove(curLineNr, textArea.TextView.VisibleLineCount), textArea.Document.TotalNumberOfLines - 1);
if (curLineNr != requestedLineNumber) {
textArea.Caret.Position = new TextLocation(0, requestedLineNumber);
textArea.SetCaretToDesiredColumn();
}
}
}
public class MovePageUp : AbstractEditAction
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
int curLineNr = textArea.Caret.Line;
int requestedLineNumber = Math.Max(textArea.Document.GetNextVisibleLineBelow(curLineNr, textArea.TextView.VisibleLineCount), 0);
if (curLineNr != requestedLineNumber) {
textArea.Caret.Position = new TextLocation(0, requestedLineNumber);
textArea.SetCaretToDesiredColumn();
}
}
}
public class Return : AbstractEditAction
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
textArea.BeginUpdate();
textArea.Document.UndoStack.StartUndoGroup();
try {
if (textArea.HandleKeyPress('\n'))
return;
textArea.InsertString(Environment.NewLine);
int curLineNr = textArea.Caret.Line;
textArea.Document.FormattingStrategy.FormatLine(textArea, curLineNr, textArea.Caret.Offset, '\n');
textArea.SetDesiredColumn();
textArea.Document.UpdateQueue.Clear();
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, curLineNr - 1)));
} finally {
textArea.Document.UndoStack.EndUndoGroup();
textArea.EndUpdate();
}
}
}
public class ToggleEditMode : AbstractEditAction
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
switch (textArea.Caret.CaretMode) {
case CaretMode.InsertMode:
textArea.Caret.CaretMode = CaretMode.OverwriteMode;
break;
case CaretMode.OverwriteMode:
textArea.Caret.CaretMode = CaretMode.InsertMode;
break;
}
}
}
public class Undo : AbstractEditAction
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
textArea.MotherTextEditorControl.Undo();
}
}
public class Redo : AbstractEditAction
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
textArea.MotherTextEditorControl.Redo();
}
}
///
/// handles the ctrl-backspace key
/// functionality attempts to roughly mimic MS Developer studio
/// I will implement this as deleting back to the point that ctrl-leftarrow would
/// take you to
///
public class WordBackspace : AbstractEditAction
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
// if anything is selected we will just delete it first
if (textArea.SelectionManager.HasSomethingSelected) {
Delete.DeleteSelection(textArea);
return;
}
textArea.BeginUpdate();
// now delete from the caret to the beginning of the word
LineSegment line =
textArea.Document.GetLineSegmentForOffset(textArea.Caret.Offset);
// if we are not at the beginning of a line
if (textArea.Caret.Offset > line.Offset) {
int prevWordStart = TextUtilities.FindPrevWordStart(textArea.Document,
textArea.Caret.Offset);
if (prevWordStart < textArea.Caret.Offset) {
if (!textArea.IsReadOnly(prevWordStart, textArea.Caret.Offset - prevWordStart)) {
textArea.Document.Remove(prevWordStart,
textArea.Caret.Offset - prevWordStart);
textArea.Caret.Position = textArea.Document.OffsetToPosition(prevWordStart);
}
}
}
// if we are now at the beginning of a line
if (textArea.Caret.Offset == line.Offset) {
// if we are not on the first line
int curLineNr = textArea.Document.GetLineNumberForOffset(textArea.Caret.Offset);
if (curLineNr > 0) {
// move to the end of the line above
LineSegment lineAbove = textArea.Document.GetLineSegment(curLineNr - 1);
int endOfLineAbove = lineAbove.Offset + lineAbove.Length;
int charsToDelete = textArea.Caret.Offset - endOfLineAbove;
if (!textArea.IsReadOnly(endOfLineAbove, charsToDelete)) {
textArea.Document.Remove(endOfLineAbove, charsToDelete);
textArea.Caret.Position = textArea.Document.OffsetToPosition(endOfLineAbove);
}
}
}
textArea.SetDesiredColumn();
textArea.EndUpdate();
// if there are now less lines, we need this or there are redraw problems
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, textArea.Document.GetLineNumberForOffset(textArea.Caret.Offset))));
textArea.Document.CommitUpdate();
}
}
///
/// handles the ctrl-delete key
/// functionality attempts to mimic MS Developer studio
/// I will implement this as deleting forwardto the point that
/// ctrl-leftarrow would take you to
///
public class DeleteWord : Delete
{
///
/// Executes this edit action
///
/// The which is used for callback purposes
public override void Execute(TextArea textArea)
{
if (textArea.SelectionManager.HasSomethingSelected) {
DeleteSelection(textArea);
return;
}
// if anything is selected we will just delete it first
textArea.BeginUpdate();
// now delete from the caret to the beginning of the word
LineSegment line = textArea.Document.GetLineSegmentForOffset(textArea.Caret.Offset);
if(textArea.Caret.Offset == line.Offset + line.Length) {
// if we are at the end of a line
base.Execute(textArea);
} else {
int nextWordStart = TextUtilities.FindNextWordStart(textArea.Document,
textArea.Caret.Offset);
if(nextWordStart > textArea.Caret.Offset) {
if (!textArea.IsReadOnly(textArea.Caret.Offset, nextWordStart - textArea.Caret.Offset)) {
textArea.Document.Remove(textArea.Caret.Offset, nextWordStart - textArea.Caret.Offset);
// cursor never moves with this command
}
}
}
textArea.UpdateMatchingBracket();
textArea.EndUpdate();
// if there are now less lines, we need this or there are redraw problems
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, textArea.Document.GetLineNumberForOffset(textArea.Caret.Offset))));
textArea.Document.CommitUpdate();
}
}
public class DeleteLine : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
int lineNr = textArea.Caret.Line;
LineSegment line = textArea.Document.GetLineSegment(lineNr);
if (textArea.IsReadOnly(line.Offset, line.Length))
return;
textArea.Document.Remove(line.Offset, line.TotalLength);
textArea.Caret.Position = textArea.Document.OffsetToPosition(line.Offset);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, lineNr)));
textArea.UpdateMatchingBracket();
textArea.Document.CommitUpdate();
}
}
public class DeleteToLineEnd : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
int lineNr = textArea.Caret.Line;
LineSegment line = textArea.Document.GetLineSegment(lineNr);
int numRemove = (line.Offset + line.Length) - textArea.Caret.Offset;
if (numRemove > 0 && !textArea.IsReadOnly(textArea.Caret.Offset, numRemove)) {
textArea.Document.Remove(textArea.Caret.Offset, numRemove);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, new TextLocation(0, lineNr)));
textArea.Document.CommitUpdate();
}
}
}
public class GotoMatchingBrace : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
BracketHighlight highlight = textArea.FindMatchingBracketHighlight();
if (highlight != null) {
TextLocation p1 = new TextLocation(highlight.CloseBrace.X + 1, highlight.CloseBrace.Y);
TextLocation p2 = new TextLocation(highlight.OpenBrace.X + 1, highlight.OpenBrace.Y);
if (p1 == textArea.Caret.Position) {
if (textArea.Document.TextEditorProperties.BracketMatchingStyle == BracketMatchingStyle.After) {
textArea.Caret.Position = p2;
} else {
textArea.Caret.Position = new TextLocation(p2.X - 1, p2.Y);
}
} else {
if (textArea.Document.TextEditorProperties.BracketMatchingStyle == BracketMatchingStyle.After) {
textArea.Caret.Position = p1;
} else {
textArea.Caret.Position = new TextLocation(p1.X - 1, p1.Y);
}
}
textArea.SetDesiredColumn();
}
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Actions/SelectionActions.cs
================================================
//
//
//
//
// $Revision: 2659 $
//
using System;
using System.Drawing;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class ShiftCaretRight : CaretRight
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftCaretLeft : CaretLeft
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftCaretUp : CaretUp
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftCaretDown : CaretDown
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftWordRight : WordRight
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftWordLeft : WordLeft
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftHome : Home
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftEnd : End
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftMoveToStart : MoveToStart
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftMoveToEnd : MoveToEnd
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftMovePageUp : MovePageUp
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftMovePageDown : MovePageDown
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class SelectWholeDocument : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.AutoClearSelection = false;
TextLocation startPoint = new TextLocation(0, 0);
TextLocation endPoint = textArea.Document.OffsetToPosition(textArea.Document.TextLength);
if (textArea.SelectionManager.HasSomethingSelected) {
if (textArea.SelectionManager.SelectionCollection[0].StartPosition == startPoint &&
textArea.SelectionManager.SelectionCollection[0].EndPosition == endPoint) {
return;
}
}
textArea.Caret.Position = textArea.SelectionManager.NextValidPosition(endPoint.Y);
textArea.SelectionManager.ExtendSelection(startPoint, endPoint);
// after a SelectWholeDocument selection, the caret is placed correctly,
// but it is not positioned internally. The effect is when the cursor
// is moved up or down a line, the caret will take on the column that
// it was in before the SelectWholeDocument
textArea.SetDesiredColumn();
}
}
public class ClearAllSelections : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.SelectionManager.ClearSelection();
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/AbstractSegment.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
namespace ICSharpCode.TextEditor.Document
{
///
/// This interface is used to describe a span inside a text sequence
///
public class AbstractSegment : ISegment
{
[CLSCompliant(false)]
protected int offset = -1;
[CLSCompliant(false)]
protected int length = -1;
#region ICSharpCode.TextEditor.Document.ISegment interface implementation
public virtual int Offset {
get {
return offset;
}
set {
offset = value;
}
}
public virtual int Length {
get {
return length;
}
set {
length = value;
}
}
#endregion
public override string ToString()
{
return String.Format("[AbstractSegment: Offset = {0}, Length = {1}]",
Offset,
Length);
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/BookmarkManager/Bookmark.cs
================================================
//
//
//
//
// $Revision: 3272 $
//
using System;
using System.Drawing;
using SWF = System.Windows.Forms;
namespace ICSharpCode.TextEditor.Document
{
///
/// Description of Bookmark.
///
public class Bookmark
{
IDocument document;
TextAnchor anchor;
TextLocation location;
bool isEnabled = true;
public IDocument Document {
get {
return document;
}
set {
if (document != value) {
if (anchor != null) {
location = anchor.Location;
anchor = null;
}
document = value;
CreateAnchor();
OnDocumentChanged(EventArgs.Empty);
}
}
}
void CreateAnchor()
{
if (document != null) {
LineSegment line = document.GetLineSegment(Math.Max(0, Math.Min(location.Line, document.TotalNumberOfLines-1)));
anchor = line.CreateAnchor(Math.Max(0, Math.Min(location.Column, line.Length)));
// after insertion: keep bookmarks after the initial whitespace (see DefaultFormattingStrategy.SmartReplaceLine)
anchor.MovementType = AnchorMovementType.AfterInsertion;
anchor.Deleted += AnchorDeleted;
}
}
void AnchorDeleted(object sender, EventArgs e)
{
document.BookmarkManager.RemoveMark(this);
}
///
/// Gets the TextAnchor used for this bookmark.
/// Is null if the bookmark is not connected to a document.
///
public TextAnchor Anchor {
get { return anchor; }
}
public TextLocation Location {
get {
if (anchor != null)
return anchor.Location;
else
return location;
}
set {
location = value;
CreateAnchor();
}
}
public event EventHandler DocumentChanged;
protected virtual void OnDocumentChanged(EventArgs e)
{
if (DocumentChanged != null) {
DocumentChanged(this, e);
}
}
public bool IsEnabled {
get {
return isEnabled;
}
set {
if (isEnabled != value) {
isEnabled = value;
if (document != null) {
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, LineNumber));
document.CommitUpdate();
}
OnIsEnabledChanged(EventArgs.Empty);
}
}
}
public event EventHandler IsEnabledChanged;
protected virtual void OnIsEnabledChanged(EventArgs e)
{
if (IsEnabledChanged != null) {
IsEnabledChanged(this, e);
}
}
public int LineNumber {
get {
if (anchor != null)
return anchor.LineNumber;
else
return location.Line;
}
}
public int ColumnNumber {
get {
if (anchor != null)
return anchor.ColumnNumber;
else
return location.Column;
}
}
///
/// Gets if the bookmark can be toggled off using the 'set/unset bookmark' command.
///
public virtual bool CanToggle {
get {
return true;
}
}
public Bookmark(IDocument document, TextLocation location) : this(document, location, true)
{
}
public Bookmark(IDocument document, TextLocation location, bool isEnabled)
{
this.document = document;
this.isEnabled = isEnabled;
this.Location = location;
}
public virtual bool Click(SWF.Control parent, SWF.MouseEventArgs e)
{
if (e.Button == SWF.MouseButtons.Left && CanToggle) {
document.BookmarkManager.RemoveMark(this);
return true;
}
return false;
}
public virtual void Draw(IconBarMargin margin, Graphics g, Point p)
{
margin.DrawBookmark(g, p.Y, isEnabled);
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/BookmarkManager/BookmarkEventHandler.cs
================================================
//
//
//
//
// $Revision: 915 $
//
using System;
namespace ICSharpCode.TextEditor.Document
{
public delegate void BookmarkEventHandler(object sender, BookmarkEventArgs e);
///
/// Description of BookmarkEventHandler.
///
public class BookmarkEventArgs : EventArgs
{
Bookmark bookmark;
public Bookmark Bookmark {
get {
return bookmark;
}
}
public BookmarkEventArgs(Bookmark bookmark)
{
this.bookmark = bookmark;
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/BookmarkManager/BookmarkManager.cs
================================================
//
//
//
//
// $Revision: 3272 $
//
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using ICSharpCode.TextEditor.Util;
namespace ICSharpCode.TextEditor.Document
{
public interface IBookmarkFactory
{
Bookmark CreateBookmark(IDocument document, TextLocation location);
}
///
/// This class handles the bookmarks for a buffer
///
public class BookmarkManager
{
IDocument document;
#if DEBUG
IList bookmark = new CheckedList();
#else
List bookmark = new List();
#endif
///
/// Contains all bookmarks
///
public ReadOnlyCollection Marks {
get {
return new ReadOnlyCollection(bookmark);
}
}
public IDocument Document {
get {
return document;
}
}
///
/// Creates a new instance of
///
internal BookmarkManager(IDocument document, LineManager lineTracker)
{
this.document = document;
}
///
/// Gets/Sets the bookmark factory used to create bookmarks for "ToggleMarkAt".
///
public IBookmarkFactory Factory { get; set;}
///
/// Sets the mark at the line location.Line if it is not set, if the
/// line is already marked the mark is cleared.
///
public void ToggleMarkAt(TextLocation location)
{
Bookmark newMark;
if (Factory != null) {
newMark = Factory.CreateBookmark(document, location);
} else {
newMark = new Bookmark(document, location);
}
Type newMarkType = newMark.GetType();
for (int i = 0; i < bookmark.Count; ++i) {
Bookmark mark = bookmark[i];
if (mark.LineNumber == location.Line && mark.CanToggle && mark.GetType() == newMarkType) {
bookmark.RemoveAt(i);
OnRemoved(new BookmarkEventArgs(mark));
return;
}
}
bookmark.Add(newMark);
OnAdded(new BookmarkEventArgs(newMark));
}
public void AddMark(Bookmark mark)
{
bookmark.Add(mark);
OnAdded(new BookmarkEventArgs(mark));
}
public void RemoveMark(Bookmark mark)
{
bookmark.Remove(mark);
OnRemoved(new BookmarkEventArgs(mark));
}
public void RemoveMarks(Predicate predicate)
{
for (int i = 0; i < bookmark.Count; ++i) {
Bookmark bm = bookmark[i];
if (predicate(bm)) {
bookmark.RemoveAt(i--);
OnRemoved(new BookmarkEventArgs(bm));
}
}
}
///
/// true, if a mark at mark exists, otherwise false
///
public bool IsMarked(int lineNr)
{
for (int i = 0; i < bookmark.Count; ++i) {
if (bookmark[i].LineNumber == lineNr) {
return true;
}
}
return false;
}
///
/// Clears all bookmark
///
public void Clear()
{
foreach (Bookmark mark in bookmark) {
OnRemoved(new BookmarkEventArgs(mark));
}
bookmark.Clear();
}
///
/// The lowest mark, if no marks exists it returns -1
///
public Bookmark GetFirstMark(Predicate predicate)
{
if (bookmark.Count < 1) {
return null;
}
Bookmark first = null;
for (int i = 0; i < bookmark.Count; ++i) {
if (predicate(bookmark[i]) && bookmark[i].IsEnabled && (first == null || bookmark[i].LineNumber < first.LineNumber)) {
first = bookmark[i];
}
}
return first;
}
///
/// The highest mark, if no marks exists it returns -1
///
public Bookmark GetLastMark(Predicate predicate)
{
if (bookmark.Count < 1) {
return null;
}
Bookmark last = null;
for (int i = 0; i < bookmark.Count; ++i) {
if (predicate(bookmark[i]) && bookmark[i].IsEnabled && (last == null || bookmark[i].LineNumber > last.LineNumber)) {
last = bookmark[i];
}
}
return last;
}
bool AcceptAnyMarkPredicate(Bookmark mark)
{
return true;
}
public Bookmark GetNextMark(int curLineNr)
{
return GetNextMark(curLineNr, AcceptAnyMarkPredicate);
}
///
/// returns first mark higher than lineNr
///
///
/// returns the next mark > cur, if it not exists it returns FirstMark()
///
public Bookmark GetNextMark(int curLineNr, Predicate predicate)
{
if (bookmark.Count == 0) {
return null;
}
Bookmark next = GetFirstMark(predicate);
foreach (Bookmark mark in bookmark) {
if (predicate(mark) && mark.IsEnabled && mark.LineNumber > curLineNr) {
if (mark.LineNumber < next.LineNumber || next.LineNumber <= curLineNr) {
next = mark;
}
}
}
return next;
}
public Bookmark GetPrevMark(int curLineNr)
{
return GetPrevMark(curLineNr, AcceptAnyMarkPredicate);
}
///
/// returns first mark lower than lineNr
///
///
/// returns the next mark lower than cur, if it not exists it returns LastMark()
///
public Bookmark GetPrevMark(int curLineNr, Predicate predicate)
{
if (bookmark.Count == 0) {
return null;
}
Bookmark prev = GetLastMark(predicate);
foreach (Bookmark mark in bookmark) {
if (predicate(mark) && mark.IsEnabled && mark.LineNumber < curLineNr) {
if (mark.LineNumber > prev.LineNumber || prev.LineNumber >= curLineNr) {
prev = mark;
}
}
}
return prev;
}
protected virtual void OnRemoved(BookmarkEventArgs e)
{
if (Removed != null) {
Removed(this, e);
}
}
protected virtual void OnAdded(BookmarkEventArgs e)
{
if (Added != null) {
Added(this, e);
}
}
public event BookmarkEventHandler Removed;
public event BookmarkEventHandler Added;
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/BookmarkManager/BookmarkManagerMemento.cs
================================================
//
//
//
//
// $Revision: 915 $
//
using System;
using System.Collections.Generic;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
///
/// This class is used for storing the state of a bookmark manager
///
public class BookmarkManagerMemento
{
List bookmarks = new List();
///
/// Contains all bookmarks as int values
///
public List Bookmarks {
get {
return bookmarks;
}
set {
bookmarks = value;
}
}
///
/// Validates all bookmarks if they're in range of the document.
/// (removing all bookmarks < 0 and bookmarks > max. line number
///
public void CheckMemento(IDocument document)
{
for (int i = 0; i < bookmarks.Count; ++i) {
int mark = (int)bookmarks[i];
if (mark < 0 || mark >= document.TotalNumberOfLines) {
bookmarks.RemoveAt(i);
--i;
}
}
}
///
/// Creates a new instance of
///
public BookmarkManagerMemento()
{
}
///
/// Creates a new instance of
///
public BookmarkManagerMemento(XmlElement element)
{
foreach (XmlElement el in element.ChildNodes) {
bookmarks.Add(Int32.Parse(el.Attributes["line"].InnerText));
}
}
///
/// Creates a new instance of
///
public BookmarkManagerMemento(List bookmarks)
{
this.bookmarks = bookmarks;
}
///
/// Converts a xml element to a object
///
public object FromXmlElement(XmlElement element)
{
return new BookmarkManagerMemento(element);
}
///
/// Converts this to a xml element
///
public XmlElement ToXmlElement(XmlDocument doc)
{
XmlElement bookmarknode = doc.CreateElement("Bookmarks");
foreach (int line in bookmarks) {
XmlElement markNode = doc.CreateElement("Mark");
XmlAttribute lineAttr = doc.CreateAttribute("line");
lineAttr.InnerText = line.ToString();
markNode.Attributes.Append(lineAttr);
bookmarknode.AppendChild(markNode);
}
return bookmarknode;
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/DefaultDocument.cs
================================================
//
//
//
//
// $Revision: 3205 $
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using ICSharpCode.TextEditor.Undo;
namespace ICSharpCode.TextEditor.Document
{
///
/// Describes the caret marker
///
public enum LineViewerStyle {
///
/// No line viewer will be displayed
///
None,
///
/// The row in which the caret is will be marked
///
FullRow
}
///
/// Describes the indent style
///
public enum IndentStyle {
///
/// No indentation occurs
///
None,
///
/// The indentation from the line above will be
/// taken to indent the curent line
///
Auto,
///
/// Inteligent, context sensitive indentation will occur
///
Smart
}
///
/// Describes the bracket highlighting style
///
public enum BracketHighlightingStyle {
///
/// Brackets won't be highlighted
///
None,
///
/// Brackets will be highlighted if the caret is on the bracket
///
OnBracket,
///
/// Brackets will be highlighted if the caret is after the bracket
///
AfterBracket
}
///
/// Describes the selection mode of the text area
///
public enum DocumentSelectionMode {
///
/// The 'normal' selection mode.
///
Normal,
///
/// Selections will be added to the current selection or new
/// ones will be created (multi-select mode)
///
Additive
}
///
/// The default implementation.
///
internal sealed class DefaultDocument : IDocument
{
bool readOnly = false;
LineManager lineTrackingStrategy;
BookmarkManager bookmarkManager;
ITextBufferStrategy textBufferStrategy;
IFormattingStrategy formattingStrategy;
FoldingManager foldingManager;
UndoStack undoStack = new UndoStack();
ITextEditorProperties textEditorProperties = new DefaultTextEditorProperties();
MarkerStrategy markerStrategy;
public LineManager LineManager {
get { return lineTrackingStrategy; }
set { lineTrackingStrategy = value; }
}
public event EventHandler LineLengthChanged {
add { lineTrackingStrategy.LineLengthChanged += value; }
remove { lineTrackingStrategy.LineLengthChanged -= value; }
}
public event EventHandler LineCountChanged {
add { lineTrackingStrategy.LineCountChanged += value; }
remove { lineTrackingStrategy.LineCountChanged -= value; }
}
public event EventHandler LineDeleted {
add { lineTrackingStrategy.LineDeleted += value; }
remove { lineTrackingStrategy.LineDeleted -= value; }
}
public MarkerStrategy MarkerStrategy {
get { return markerStrategy; }
set { markerStrategy = value; }
}
public ITextEditorProperties TextEditorProperties {
get {
return textEditorProperties;
}
set {
textEditorProperties = value;
}
}
public UndoStack UndoStack {
get {
return undoStack;
}
}
public IList LineSegmentCollection {
get {
return lineTrackingStrategy.LineSegmentCollection;
}
}
public bool ReadOnly {
get {
return readOnly;
}
set {
readOnly = value;
}
}
public ITextBufferStrategy TextBufferStrategy {
get {
return textBufferStrategy;
}
set {
textBufferStrategy = value;
}
}
public IFormattingStrategy FormattingStrategy {
get {
return formattingStrategy;
}
set {
formattingStrategy = value;
}
}
public FoldingManager FoldingManager {
get {
return foldingManager;
}
set {
foldingManager = value;
}
}
public IHighlightingStrategy HighlightingStrategy {
get {
return lineTrackingStrategy.HighlightingStrategy;
}
set {
lineTrackingStrategy.HighlightingStrategy = value;
}
}
public int TextLength {
get {
return textBufferStrategy.Length;
}
}
public BookmarkManager BookmarkManager {
get {
return bookmarkManager;
}
set {
bookmarkManager = value;
}
}
public string TextContent {
get {
return GetText(0, textBufferStrategy.Length);
}
set {
Debug.Assert(textBufferStrategy != null);
Debug.Assert(lineTrackingStrategy != null);
OnDocumentAboutToBeChanged(new DocumentEventArgs(this, 0, 0, value));
textBufferStrategy.SetContent(value);
lineTrackingStrategy.SetContent(value);
undoStack.ClearAll();
OnDocumentChanged(new DocumentEventArgs(this, 0, 0, value));
OnTextContentChanged(EventArgs.Empty);
}
}
public void Insert(int offset, string text)
{
if (readOnly) {
return;
}
OnDocumentAboutToBeChanged(new DocumentEventArgs(this, offset, -1, text));
textBufferStrategy.Insert(offset, text);
lineTrackingStrategy.Insert(offset, text);
undoStack.Push(new UndoableInsert(this, offset, text));
OnDocumentChanged(new DocumentEventArgs(this, offset, -1, text));
}
public void Remove(int offset, int length)
{
if (readOnly) {
return;
}
OnDocumentAboutToBeChanged(new DocumentEventArgs(this, offset, length));
undoStack.Push(new UndoableDelete(this, offset, GetText(offset, length)));
textBufferStrategy.Remove(offset, length);
lineTrackingStrategy.Remove(offset, length);
OnDocumentChanged(new DocumentEventArgs(this, offset, length));
}
public void Replace(int offset, int length, string text)
{
if (readOnly) {
return;
}
OnDocumentAboutToBeChanged(new DocumentEventArgs(this, offset, length, text));
undoStack.Push(new UndoableReplace(this, offset, GetText(offset, length), text));
textBufferStrategy.Replace(offset, length, text);
lineTrackingStrategy.Replace(offset, length, text);
OnDocumentChanged(new DocumentEventArgs(this, offset, length, text));
}
public char GetCharAt(int offset)
{
return textBufferStrategy.GetCharAt(offset);
}
public string GetText(int offset, int length)
{
#if DEBUG
if (length < 0) throw new ArgumentOutOfRangeException("length", length, "length < 0");
#endif
return textBufferStrategy.GetText(offset, length);
}
public string GetText(ISegment segment)
{
return GetText(segment.Offset, segment.Length);
}
public int TotalNumberOfLines {
get {
return lineTrackingStrategy.TotalNumberOfLines;
}
}
public int GetLineNumberForOffset(int offset)
{
return lineTrackingStrategy.GetLineNumberForOffset(offset);
}
public LineSegment GetLineSegmentForOffset(int offset)
{
return lineTrackingStrategy.GetLineSegmentForOffset(offset);
}
public LineSegment GetLineSegment(int line)
{
return lineTrackingStrategy.GetLineSegment(line);
}
public int GetFirstLogicalLine(int lineNumber)
{
return lineTrackingStrategy.GetFirstLogicalLine(lineNumber);
}
public int GetLastLogicalLine(int lineNumber)
{
return lineTrackingStrategy.GetLastLogicalLine(lineNumber);
}
public int GetVisibleLine(int lineNumber)
{
return lineTrackingStrategy.GetVisibleLine(lineNumber);
}
// public int GetVisibleColumn(int logicalLine, int logicalColumn)
// {
// return lineTrackingStrategy.GetVisibleColumn(logicalLine, logicalColumn);
// }
//
public int GetNextVisibleLineAbove(int lineNumber, int lineCount)
{
return lineTrackingStrategy.GetNextVisibleLineAbove(lineNumber, lineCount);
}
public int GetNextVisibleLineBelow(int lineNumber, int lineCount)
{
return lineTrackingStrategy.GetNextVisibleLineBelow(lineNumber, lineCount);
}
public TextLocation OffsetToPosition(int offset)
{
int lineNr = GetLineNumberForOffset(offset);
LineSegment line = GetLineSegment(lineNr);
return new TextLocation(offset - line.Offset, lineNr);
}
public int PositionToOffset(TextLocation p)
{
if (p.Y >= this.TotalNumberOfLines) {
return 0;
}
LineSegment line = GetLineSegment(p.Y);
return Math.Min(this.TextLength, line.Offset + Math.Min(line.Length, p.X));
}
public void UpdateSegmentListOnDocumentChange(List list, DocumentEventArgs e) where T : ISegment
{
int removedCharacters = e.Length > 0 ? e.Length : 0;
int insertedCharacters = e.Text != null ? e.Text.Length : 0;
for (int i = 0; i < list.Count; ++i) {
ISegment s = list[i];
int segmentStart = s.Offset;
int segmentEnd = s.Offset + s.Length;
if (e.Offset <= segmentStart) {
segmentStart -= removedCharacters;
if (segmentStart < e.Offset)
segmentStart = e.Offset;
}
if (e.Offset < segmentEnd) {
segmentEnd -= removedCharacters;
if (segmentEnd < e.Offset)
segmentEnd = e.Offset;
}
Debug.Assert(segmentStart <= segmentEnd);
if (segmentStart == segmentEnd) {
list.RemoveAt(i);
--i;
continue;
}
if (e.Offset <= segmentStart)
segmentStart += insertedCharacters;
if (e.Offset < segmentEnd)
segmentEnd += insertedCharacters;
Debug.Assert(segmentStart < segmentEnd);
s.Offset = segmentStart;
s.Length = segmentEnd - segmentStart;
}
}
void OnDocumentAboutToBeChanged(DocumentEventArgs e)
{
if (DocumentAboutToBeChanged != null) {
DocumentAboutToBeChanged(this, e);
}
}
void OnDocumentChanged(DocumentEventArgs e)
{
if (DocumentChanged != null) {
DocumentChanged(this, e);
}
}
public event DocumentEventHandler DocumentAboutToBeChanged;
public event DocumentEventHandler DocumentChanged;
// UPDATE STUFF
List updateQueue = new List();
public List UpdateQueue {
get {
return updateQueue;
}
}
public void RequestUpdate(TextAreaUpdate update)
{
if (updateQueue.Count == 1 && updateQueue[0].TextAreaUpdateType == TextAreaUpdateType.WholeTextArea) {
// if we're going to update the whole text area, we don't need to store detail updates
return;
}
if (update.TextAreaUpdateType == TextAreaUpdateType.WholeTextArea) {
// if we're going to update the whole text area, we don't need to store detail updates
updateQueue.Clear();
}
updateQueue.Add(update);
}
public void CommitUpdate()
{
if (UpdateCommited != null) {
UpdateCommited(this, EventArgs.Empty);
}
}
void OnTextContentChanged(EventArgs e)
{
if (TextContentChanged != null) {
TextContentChanged(this, e);
}
}
public event EventHandler UpdateCommited;
public event EventHandler TextContentChanged;
[Conditional("DEBUG")]
internal static void ValidatePosition(IDocument document, TextLocation position)
{
document.GetLineSegment(position.Line);
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/DefaultTextEditorProperties.cs
================================================
//
//
//
//
// $Revision: 3205 $
//
using System;
using System.Drawing;
using System.Text;
namespace ICSharpCode.TextEditor.Document
{
public enum BracketMatchingStyle {
Before,
After
}
public class DefaultTextEditorProperties : ITextEditorProperties
{
int tabIndent = 4;
int indentationSize = 4;
IndentStyle indentStyle = IndentStyle.Smart;
DocumentSelectionMode documentSelectionMode = DocumentSelectionMode.Normal;
Encoding encoding = System.Text.Encoding.UTF8;
BracketMatchingStyle bracketMatchingStyle = BracketMatchingStyle.After;
FontContainer fontContainer;
static Font DefaultFont;
public DefaultTextEditorProperties()
{
if (DefaultFont == null) {
DefaultFont = new Font("Courier New", 10);
}
this.fontContainer = new FontContainer(DefaultFont);
}
bool allowCaretBeyondEOL = false;
bool showMatchingBracket = true;
bool showLineNumbers = true;
bool showSpaces = false;
bool showTabs = false;
bool showEOLMarker = false;
bool showInvalidLines = false;
bool isIconBarVisible = false;
bool enableFolding = true;
bool showHorizontalRuler = false;
bool showVerticalRuler = true;
bool convertTabsToSpaces = false;
System.Drawing.Text.TextRenderingHint textRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
bool mouseWheelScrollDown = true;
bool mouseWheelTextZoom = true;
bool hideMouseCursor = false;
bool cutCopyWholeLine = true;
int verticalRulerRow = 80;
LineViewerStyle lineViewerStyle = LineViewerStyle.None;
string lineTerminator = "\r\n";
bool autoInsertCurlyBracket = true;
bool supportReadOnlySegments = false;
public int TabIndent {
get {
return tabIndent;
}
set {
tabIndent = value;
}
}
public int IndentationSize {
get { return indentationSize; }
set { indentationSize = value; }
}
public IndentStyle IndentStyle {
get {
return indentStyle;
}
set {
indentStyle = value;
}
}
public DocumentSelectionMode DocumentSelectionMode {
get {
return documentSelectionMode;
}
set {
documentSelectionMode = value;
}
}
public bool AllowCaretBeyondEOL {
get {
return allowCaretBeyondEOL;
}
set {
allowCaretBeyondEOL = value;
}
}
public bool ShowMatchingBracket {
get {
return showMatchingBracket;
}
set {
showMatchingBracket = value;
}
}
public bool ShowLineNumbers {
get {
return showLineNumbers;
}
set {
showLineNumbers = value;
}
}
public bool ShowSpaces {
get {
return showSpaces;
}
set {
showSpaces = value;
}
}
public bool ShowTabs {
get {
return showTabs;
}
set {
showTabs = value;
}
}
public bool ShowEOLMarker {
get {
return showEOLMarker;
}
set {
showEOLMarker = value;
}
}
public bool ShowInvalidLines {
get {
return showInvalidLines;
}
set {
showInvalidLines = value;
}
}
public bool IsIconBarVisible {
get {
return isIconBarVisible;
}
set {
isIconBarVisible = value;
}
}
public bool EnableFolding {
get {
return enableFolding;
}
set {
enableFolding = value;
}
}
public bool ShowHorizontalRuler {
get {
return showHorizontalRuler;
}
set {
showHorizontalRuler = value;
}
}
public bool ShowVerticalRuler {
get {
return showVerticalRuler;
}
set {
showVerticalRuler = value;
}
}
public bool ConvertTabsToSpaces {
get {
return convertTabsToSpaces;
}
set {
convertTabsToSpaces = value;
}
}
public System.Drawing.Text.TextRenderingHint TextRenderingHint {
get { return textRenderingHint; }
set { textRenderingHint = value; }
}
public bool MouseWheelScrollDown {
get {
return mouseWheelScrollDown;
}
set {
mouseWheelScrollDown = value;
}
}
public bool MouseWheelTextZoom {
get {
return mouseWheelTextZoom;
}
set {
mouseWheelTextZoom = value;
}
}
public bool HideMouseCursor {
get {
return hideMouseCursor;
}
set {
hideMouseCursor = value;
}
}
public bool CutCopyWholeLine {
get {
return cutCopyWholeLine;
}
set {
cutCopyWholeLine = value;
}
}
public Encoding Encoding {
get {
return encoding;
}
set {
encoding = value;
}
}
public int VerticalRulerRow {
get {
return verticalRulerRow;
}
set {
verticalRulerRow = value;
}
}
public LineViewerStyle LineViewerStyle {
get {
return lineViewerStyle;
}
set {
lineViewerStyle = value;
}
}
public string LineTerminator {
get {
return lineTerminator;
}
set {
lineTerminator = value;
}
}
public bool AutoInsertCurlyBracket {
get {
return autoInsertCurlyBracket;
}
set {
autoInsertCurlyBracket = value;
}
}
public Font Font {
get {
return fontContainer.DefaultFont;
}
set {
fontContainer.DefaultFont = value;
}
}
public FontContainer FontContainer {
get {
return fontContainer;
}
}
public BracketMatchingStyle BracketMatchingStyle {
get {
return bracketMatchingStyle;
}
set {
bracketMatchingStyle = value;
}
}
public bool SupportReadOnlySegments {
get {
return supportReadOnlySegments;
}
set {
supportReadOnlySegments = value;
}
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/DocumentEventArgs.cs
================================================
//
//
//
//
// $Revision: 915 $
//
using System;
namespace ICSharpCode.TextEditor.Document
{
///
/// This delegate is used for document events.
///
public delegate void DocumentEventHandler(object sender, DocumentEventArgs e);
///
/// This class contains more information on a document event
///
public class DocumentEventArgs : EventArgs
{
IDocument document;
int offset;
int length;
string text;
///
/// always a valid Document which is related to the Event.
///
public IDocument Document {
get {
return document;
}
}
///
/// -1 if no offset was specified for this event
///
public int Offset {
get {
return offset;
}
}
///
/// null if no text was specified for this event
///
public string Text {
get {
return text;
}
}
///
/// -1 if no length was specified for this event
///
public int Length {
get {
return length;
}
}
///
/// Creates a new instance off
///
public DocumentEventArgs(IDocument document) : this(document, -1, -1, null)
{
}
///
/// Creates a new instance off
///
public DocumentEventArgs(IDocument document, int offset) : this(document, offset, -1, null)
{
}
///
/// Creates a new instance off
///
public DocumentEventArgs(IDocument document, int offset, int length) : this(document, offset, length, null)
{
}
///
/// Creates a new instance off
///
public DocumentEventArgs(IDocument document, int offset, int length, string text)
{
this.document = document;
this.offset = offset;
this.length = length;
this.text = text;
}
public override string ToString()
{
return String.Format("[DocumentEventArgs: Document = {0}, Offset = {1}, Text = {2}, Length = {3}]",
Document,
Offset,
Text,
Length);
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/DocumentFactory.cs
================================================
//
//
//
//
// $Revision: 3205 $
//
using System;
using System.Text;
namespace ICSharpCode.TextEditor.Document
{
///
/// This interface represents a container which holds a text sequence and
/// all necessary information about it. It is used as the base for a text editor.
///
public class DocumentFactory
{
///
/// Creates a new object. Only create
/// with this method.
///
public IDocument CreateDocument()
{
DefaultDocument doc = new DefaultDocument();
doc.TextBufferStrategy = new GapTextBufferStrategy();
doc.FormattingStrategy = new DefaultFormattingStrategy();
doc.LineManager = new LineManager(doc, null);
doc.FoldingManager = new FoldingManager(doc, doc.LineManager);
doc.FoldingManager.FoldingStrategy = null; //new ParserFoldingStrategy();
doc.MarkerStrategy = new MarkerStrategy(doc);
doc.BookmarkManager = new BookmarkManager(doc, doc.LineManager);
return doc;
}
///
/// Creates a new document and loads the given file
///
public IDocument CreateFromTextBuffer(ITextBufferStrategy textBuffer)
{
DefaultDocument doc = (DefaultDocument)CreateDocument();
doc.TextContent = textBuffer.GetText(0, textBuffer.Length);
doc.TextBufferStrategy = textBuffer;
return doc;
}
///
/// Creates a new document and loads the given file
///
public IDocument CreateFromFile(string fileName)
{
IDocument document = CreateDocument();
document.TextContent = Util.FileReader.ReadFileContent(fileName, Encoding.Default);
return document;
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/FoldingStrategy/FoldMarker.cs
================================================
//
//
//
//
// $Revision: 2063 $
//
using System;
namespace ICSharpCode.TextEditor.Document
{
public enum FoldType {
Unspecified,
MemberBody,
Region,
TypeBody
}
public class FoldMarker : AbstractSegment, IComparable
{
bool isFolded = false;
string foldText = "...";
FoldType foldType = FoldType.Unspecified;
IDocument document = null;
int startLine = -1, startColumn, endLine = -1, endColumn;
static void GetPointForOffset(IDocument document, int offset, out int line, out int column)
{
if (offset > document.TextLength) {
line = document.TotalNumberOfLines + 1;
column = 1;
} else if (offset < 0) {
line = -1;
column = -1;
} else {
line = document.GetLineNumberForOffset(offset);
column = offset - document.GetLineSegment(line).Offset;
}
}
public FoldType FoldType {
get { return foldType; }
set { foldType = value; }
}
public int StartLine {
get {
if (startLine < 0) {
GetPointForOffset(document, offset, out startLine, out startColumn);
}
return startLine;
}
}
public int StartColumn {
get {
if (startLine < 0) {
GetPointForOffset(document, offset, out startLine, out startColumn);
}
return startColumn;
}
}
public int EndLine {
get {
if (endLine < 0) {
GetPointForOffset(document, offset + length, out endLine, out endColumn);
}
return endLine;
}
}
public int EndColumn {
get {
if (endLine < 0) {
GetPointForOffset(document, offset + length, out endLine, out endColumn);
}
return endColumn;
}
}
public override int Offset {
get { return base.Offset; }
set {
base.Offset = value;
startLine = -1; endLine = -1;
}
}
public override int Length {
get { return base.Length; }
set {
base.Length = value;
endLine = -1;
}
}
public bool IsFolded {
get {
return isFolded;
}
set {
isFolded = value;
}
}
public string FoldText {
get {
return foldText;
}
}
public string InnerText {
get {
return document.GetText(offset, length);
}
}
public FoldMarker(IDocument document, int offset, int length, string foldText, bool isFolded)
{
this.document = document;
this.offset = offset;
this.length = length;
this.foldText = foldText;
this.isFolded = isFolded;
}
public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn) : this(document, startLine, startColumn, endLine, endColumn, FoldType.Unspecified)
{
}
public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn, FoldType foldType) : this(document, startLine, startColumn, endLine, endColumn, foldType, "...")
{
}
public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn, FoldType foldType, string foldText) : this(document, startLine, startColumn, endLine, endColumn, foldType, foldText, false)
{
}
public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn, FoldType foldType, string foldText, bool isFolded)
{
this.document = document;
startLine = Math.Min(document.TotalNumberOfLines - 1, Math.Max(startLine, 0));
ISegment startLineSegment = document.GetLineSegment(startLine);
endLine = Math.Min(document.TotalNumberOfLines - 1, Math.Max(endLine, 0));
ISegment endLineSegment = document.GetLineSegment(endLine);
// Prevent the region from completely disappearing
if (string.IsNullOrEmpty(foldText)) {
foldText = "...";
}
this.FoldType = foldType;
this.foldText = foldText;
this.offset = startLineSegment.Offset + Math.Min(startColumn, startLineSegment.Length);
this.length = (endLineSegment.Offset + Math.Min(endColumn, endLineSegment.Length)) - this.offset;
this.isFolded = isFolded;
}
public int CompareTo(object o)
{
if (!(o is FoldMarker)) {
throw new ArgumentException();
}
FoldMarker f = (FoldMarker)o;
if (offset != f.offset) {
return offset.CompareTo(f.offset);
}
return length.CompareTo(f.length);
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/FoldingStrategy/FoldingManager.cs
================================================
//
//
//
//
// $Revision: 2691 $
//
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace ICSharpCode.TextEditor.Document
{
public class FoldingManager
{
List foldMarker = new List();
List foldMarkerByEnd = new List();
IFoldingStrategy foldingStrategy = null;
IDocument document;
public IList FoldMarker {
get {
return foldMarker.AsReadOnly();
}
}
public IFoldingStrategy FoldingStrategy {
get {
return foldingStrategy;
}
set {
foldingStrategy = value;
}
}
internal FoldingManager(IDocument document, LineManager lineTracker)
{
this.document = document;
document.DocumentChanged += new DocumentEventHandler(DocumentChanged);
// lineTracker.LineCountChanged += new LineManagerEventHandler(LineManagerLineCountChanged);
// lineTracker.LineLengthChanged += new LineLengthEventHandler(LineManagerLineLengthChanged);
// foldMarker.Add(new FoldMarker(0, 5, 3, 5));
//
// foldMarker.Add(new FoldMarker(5, 5, 10, 3));
// foldMarker.Add(new FoldMarker(6, 0, 8, 2));
//
// FoldMarker fm1 = new FoldMarker(10, 4, 10, 7);
// FoldMarker fm2 = new FoldMarker(10, 10, 10, 14);
//
// fm1.IsFolded = true;
// fm2.IsFolded = true;
//
// foldMarker.Add(fm1);
// foldMarker.Add(fm2);
// foldMarker.Sort();
}
void DocumentChanged(object sender, DocumentEventArgs e)
{
int oldCount = foldMarker.Count;
document.UpdateSegmentListOnDocumentChange(foldMarker, e);
if (oldCount != foldMarker.Count) {
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
}
}
public List GetFoldingsFromPosition(int line, int column)
{
List foldings = new List();
if (foldMarker != null) {
for (int i = 0; i < foldMarker.Count; ++i) {
FoldMarker fm = foldMarker[i];
if ((fm.StartLine == line && column > fm.StartColumn && !(fm.EndLine == line && column >= fm.EndColumn)) ||
(fm.EndLine == line && column < fm.EndColumn && !(fm.StartLine == line && column <= fm.StartColumn)) ||
(line > fm.StartLine && line < fm.EndLine)) {
foldings.Add(fm);
}
}
}
return foldings;
}
class StartComparer : IComparer
{
public readonly static StartComparer Instance = new StartComparer();
public int Compare(FoldMarker x, FoldMarker y)
{
if (x.StartLine < y.StartLine)
return -1;
else if (x.StartLine == y.StartLine)
return x.StartColumn.CompareTo(y.StartColumn);
else
return 1;
}
}
class EndComparer : IComparer
{
public readonly static EndComparer Instance = new EndComparer();
public int Compare(FoldMarker x, FoldMarker y)
{
if (x.EndLine < y.EndLine)
return -1;
else if (x.EndLine == y.EndLine)
return x.EndColumn.CompareTo(y.EndColumn);
else
return 1;
}
}
List GetFoldingsByStartAfterColumn(int lineNumber, int column, bool forceFolded)
{
List foldings = new List();
if (foldMarker != null) {
int index = foldMarker.BinarySearch(
new FoldMarker(document, lineNumber, column, lineNumber, column),
StartComparer.Instance);
if (index < 0) index = ~index;
for (; index < foldMarker.Count; index++) {
FoldMarker fm = foldMarker[index];
if (fm.StartLine > lineNumber)
break;
if (fm.StartColumn <= column)
continue;
if (!forceFolded || fm.IsFolded)
foldings.Add(fm);
}
}
return foldings;
}
public List GetFoldingsWithStart(int lineNumber)
{
return GetFoldingsByStartAfterColumn(lineNumber, -1, false);
}
public List GetFoldedFoldingsWithStart(int lineNumber)
{
return GetFoldingsByStartAfterColumn(lineNumber, -1, true);
}
public List GetFoldedFoldingsWithStartAfterColumn(int lineNumber, int column)
{
return GetFoldingsByStartAfterColumn(lineNumber, column, true);
}
List GetFoldingsByEndAfterColumn(int lineNumber, int column, bool forceFolded)
{
List foldings = new List();
if (foldMarker != null) {
int index = foldMarkerByEnd.BinarySearch(
new FoldMarker(document, lineNumber, column, lineNumber, column),
EndComparer.Instance);
if (index < 0) index = ~index;
for (; index < foldMarkerByEnd.Count; index++) {
FoldMarker fm = foldMarkerByEnd[index];
if (fm.EndLine > lineNumber)
break;
if (fm.EndColumn <= column)
continue;
if (!forceFolded || fm.IsFolded)
foldings.Add(fm);
}
}
return foldings;
}
public List GetFoldingsWithEnd(int lineNumber)
{
return GetFoldingsByEndAfterColumn(lineNumber, -1, false);
}
public List GetFoldedFoldingsWithEnd(int lineNumber)
{
return GetFoldingsByEndAfterColumn(lineNumber, -1, true);
}
public bool IsFoldStart(int lineNumber)
{
return GetFoldingsWithStart(lineNumber).Count > 0;
}
public bool IsFoldEnd(int lineNumber)
{
return GetFoldingsWithEnd(lineNumber).Count > 0;
}
public List GetFoldingsContainsLineNumber(int lineNumber)
{
List foldings = new List();
if (foldMarker != null) {
foreach (FoldMarker fm in foldMarker) {
if (fm.StartLine < lineNumber && lineNumber < fm.EndLine) {
foldings.Add(fm);
}
}
}
return foldings;
}
public bool IsBetweenFolding(int lineNumber)
{
return GetFoldingsContainsLineNumber(lineNumber).Count > 0;
}
public bool IsLineVisible(int lineNumber)
{
foreach (FoldMarker fm in GetFoldingsContainsLineNumber(lineNumber)) {
if (fm.IsFolded)
return false;
}
return true;
}
public List GetTopLevelFoldedFoldings()
{
List foldings = new List();
if (foldMarker != null) {
Point end = new Point(0, 0);
foreach (FoldMarker fm in foldMarker) {
if (fm.IsFolded && (fm.StartLine > end.Y || fm.StartLine == end.Y && fm.StartColumn >= end.X)) {
foldings.Add(fm);
end = new Point(fm.EndColumn, fm.EndLine);
}
}
}
return foldings;
}
public void UpdateFoldings(string fileName, object parseInfo)
{
UpdateFoldings(foldingStrategy.GenerateFoldMarkers(document, fileName, parseInfo));
}
public void UpdateFoldings(List newFoldings)
{
int oldFoldingsCount = foldMarker.Count;
lock (this) {
if (newFoldings != null && newFoldings.Count != 0) {
newFoldings.Sort();
if (foldMarker.Count == newFoldings.Count) {
for (int i = 0; i < foldMarker.Count; ++i) {
newFoldings[i].IsFolded = foldMarker[i].IsFolded;
}
foldMarker = newFoldings;
} else {
for (int i = 0, j = 0; i < foldMarker.Count && j < newFoldings.Count;) {
int n = newFoldings[j].CompareTo(foldMarker[i]);
if (n > 0) {
++i;
} else {
if (n == 0) {
newFoldings[j].IsFolded = foldMarker[i].IsFolded;
}
++j;
}
}
}
}
if (newFoldings != null) {
foldMarker = newFoldings;
foldMarkerByEnd = new List(newFoldings);
foldMarkerByEnd.Sort(EndComparer.Instance);
} else {
foldMarker.Clear();
foldMarkerByEnd.Clear();
}
}
if (oldFoldingsCount != foldMarker.Count) {
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
document.CommitUpdate();
}
}
public string SerializeToString()
{
StringBuilder sb = new StringBuilder();
foreach (FoldMarker marker in this.foldMarker) {
sb.Append(marker.Offset);sb.Append("\n");
sb.Append(marker.Length);sb.Append("\n");
sb.Append(marker.FoldText);sb.Append("\n");
sb.Append(marker.IsFolded);sb.Append("\n");
}
return sb.ToString();
}
public void DeserializeFromString(string str)
{
try {
string[] lines = str.Split('\n');
for (int i = 0; i < lines.Length && lines[i].Length > 0; i += 4) {
int offset = Int32.Parse(lines[i]);
int length = Int32.Parse(lines[i + 1]);
string text = lines[i + 2];
bool isFolded = Boolean.Parse(lines[i + 3]);
bool found = false;
foreach (FoldMarker marker in foldMarker) {
if (marker.Offset == offset && marker.Length == length) {
marker.IsFolded = isFolded;
found = true;
break;
}
}
if (!found) {
foldMarker.Add(new FoldMarker(document, offset, length, text, isFolded));
}
}
if (lines.Length > 0) {
NotifyFoldingsChanged(EventArgs.Empty);
}
} catch (Exception) {
}
}
public void NotifyFoldingsChanged(EventArgs e)
{
if (FoldingsChanged != null) {
FoldingsChanged(this, e);
}
}
public event EventHandler FoldingsChanged;
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/FoldingStrategy/IFoldingStrategy.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
using System.Collections.Generic;
namespace ICSharpCode.TextEditor.Document
{
///
/// This interface is used for the folding capabilities
/// of the textarea.
///
public interface IFoldingStrategy
{
///
/// Calculates the fold level of a specific line.
///
List GenerateFoldMarkers(IDocument document, string fileName, object parseInformation);
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/FoldingStrategy/IndentFoldingStrategy.cs
================================================
//
//
//
//
// $Revision: 915 $
//
using System;
using System.Collections.Generic;
namespace ICSharpCode.TextEditor.Document
{
///
/// A simple folding strategy which calculates the folding level
/// using the indent level of the line.
///
public class IndentFoldingStrategy : IFoldingStrategy
{
public List GenerateFoldMarkers(IDocument document, string fileName, object parseInformation)
{
List l = new List();
Stack offsetStack = new Stack();
Stack textStack = new Stack();
//int level = 0;
//foreach (LineSegment segment in document.LineSegmentCollection) {
//
//}
return l;
}
int GetLevel(IDocument document, int offset)
{
int level = 0;
int spaces = 0;
for (int i = offset; i < document.TextLength; ++i) {
char c = document.GetCharAt(i);
if (c == '\t' || (c == ' ' && ++spaces == 4)) {
spaces = 0;
++level;
} else {
break;
}
}
return level;
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/FormattingStrategy/DefaultFormattingStrategy.cs
================================================
//
//
//
//
// $Revision: 3272 $
//
using System;
using System.Text;
namespace ICSharpCode.TextEditor.Document
{
///
/// This class handles the auto and smart indenting in the textbuffer while
/// you type.
///
public class DefaultFormattingStrategy : IFormattingStrategy
{
///
/// Creates a new instance off
///
public DefaultFormattingStrategy()
{
}
///
/// returns the whitespaces which are before a non white space character in the line line
/// as a string.
///
protected string GetIndentation(TextArea textArea, int lineNumber)
{
if (lineNumber < 0 || lineNumber > textArea.Document.TotalNumberOfLines) {
throw new ArgumentOutOfRangeException("lineNumber");
}
string lineText = TextUtilities.GetLineAsString(textArea.Document, lineNumber);
StringBuilder whitespaces = new StringBuilder();
foreach (char ch in lineText) {
if (Char.IsWhiteSpace(ch)) {
whitespaces.Append(ch);
} else {
break;
}
}
return whitespaces.ToString();
}
///
/// Could be overwritten to define more complex indenting.
///
protected virtual int AutoIndentLine(TextArea textArea, int lineNumber)
{
string indentation = lineNumber != 0 ? GetIndentation(textArea, lineNumber - 1) : "";
if(indentation.Length > 0) {
string newLineText = indentation + TextUtilities.GetLineAsString(textArea.Document, lineNumber).Trim();
LineSegment oldLine = textArea.Document.GetLineSegment(lineNumber);
SmartReplaceLine(textArea.Document, oldLine, newLineText);
}
return indentation.Length;
}
static readonly char[] whitespaceChars = {' ', '\t'};
///
/// Replaces the text in a line.
/// If only whitespace at the beginning and end of the line was changed, this method
/// only adjusts the whitespace and doesn't replace the other text.
///
public static void SmartReplaceLine(IDocument document, LineSegment line, string newLineText)
{
if (document == null)
throw new ArgumentNullException("document");
if (line == null)
throw new ArgumentNullException("line");
if (newLineText == null)
throw new ArgumentNullException("newLineText");
string newLineTextTrim = newLineText.Trim(whitespaceChars);
string oldLineText = document.GetText(line);
if (oldLineText == newLineText)
return;
int pos = oldLineText.IndexOf(newLineTextTrim);
if (newLineTextTrim.Length > 0 && pos >= 0) {
document.UndoStack.StartUndoGroup();
try {
// find whitespace at beginning
int startWhitespaceLength = 0;
while (startWhitespaceLength < newLineText.Length) {
char c = newLineText[startWhitespaceLength];
if (c != ' ' && c != '\t')
break;
startWhitespaceLength++;
}
// find whitespace at end
int endWhitespaceLength = newLineText.Length - newLineTextTrim.Length - startWhitespaceLength;
// replace whitespace sections
int lineOffset = line.Offset;
document.Replace(lineOffset + pos + newLineTextTrim.Length, line.Length - pos - newLineTextTrim.Length, newLineText.Substring(newLineText.Length - endWhitespaceLength));
document.Replace(lineOffset, pos, newLineText.Substring(0, startWhitespaceLength));
} finally {
document.UndoStack.EndUndoGroup();
}
} else {
document.Replace(line.Offset, line.Length, newLineText);
}
}
///
/// Could be overwritten to define more complex indenting.
///
protected virtual int SmartIndentLine(TextArea textArea, int line)
{
return AutoIndentLine(textArea, line); // smart = autoindent in normal texts
}
///
/// This function formats a specific line after ch is pressed.
///
///
/// the caret delta position the caret will be moved this number
/// of bytes (e.g. the number of bytes inserted before the caret, or
/// removed, if this number is negative)
///
public virtual void FormatLine(TextArea textArea, int line, int cursorOffset, char ch)
{
if (ch == '\n') {
textArea.Caret.Column = IndentLine(textArea, line);
}
}
///
/// This function sets the indentation level in a specific line
///
///
/// the number of inserted characters.
///
public int IndentLine(TextArea textArea, int line)
{
textArea.Document.UndoStack.StartUndoGroup();
int result;
switch (textArea.Document.TextEditorProperties.IndentStyle) {
case IndentStyle.None:
result = 0;
break;
case IndentStyle.Auto:
result = AutoIndentLine(textArea, line);
break;
case IndentStyle.Smart:
result = SmartIndentLine(textArea, line);
break;
default:
throw new NotSupportedException("Unsupported value for IndentStyle: " + textArea.Document.TextEditorProperties.IndentStyle);
}
textArea.Document.UndoStack.EndUndoGroup();
return result;
}
///
/// This function sets the indentlevel in a range of lines.
///
public virtual void IndentLines(TextArea textArea, int begin, int end)
{
textArea.Document.UndoStack.StartUndoGroup();
for (int i = begin; i <= end; ++i) {
IndentLine(textArea, i);
}
textArea.Document.UndoStack.EndUndoGroup();
}
public virtual int SearchBracketBackward(IDocument document, int offset, char openBracket, char closingBracket)
{
int brackets = -1;
// first try "quick find" - find the matching bracket if there is no string/comment in the way
for (int i = offset; i >= 0; --i) {
char ch = document.GetCharAt(i);
if (ch == openBracket) {
++brackets;
if (brackets == 0) return i;
} else if (ch == closingBracket) {
--brackets;
} else if (ch == '"') {
break;
} else if (ch == '\'') {
break;
} else if (ch == '/' && i > 0) {
if (document.GetCharAt(i - 1) == '/') break;
if (document.GetCharAt(i - 1) == '*') break;
}
}
return -1;
}
public virtual int SearchBracketForward(IDocument document, int offset, char openBracket, char closingBracket)
{
int brackets = 1;
// try "quick find" - find the matching bracket if there is no string/comment in the way
for (int i = offset; i < document.TextLength; ++i) {
char ch = document.GetCharAt(i);
if (ch == openBracket) {
++brackets;
} else if (ch == closingBracket) {
--brackets;
if (brackets == 0) return i;
} else if (ch == '"') {
break;
} else if (ch == '\'') {
break;
} else if (ch == '/' && i > 0) {
if (document.GetCharAt(i - 1) == '/') break;
} else if (ch == '*' && i > 0) {
if (document.GetCharAt(i - 1) == '/') break;
}
}
return -1;
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/FormattingStrategy/IFormattingStrategy.cs
================================================
//
//
//
//
// $Revision: 2640 $
//
using System;
namespace ICSharpCode.TextEditor.Document
{
///
/// This interface handles the auto and smart indenting and formating
/// in the document while you type. Language bindings could overwrite this
/// interface and define their own indentation/formating.
///
public interface IFormattingStrategy
{
///
/// This function formats a specific line after ch is pressed.
///
void FormatLine(TextArea textArea, int line, int caretOffset, char charTyped);
///
/// This function sets the indentation level in a specific line
///
///
/// The target caret position (length of new indentation).
///
int IndentLine(TextArea textArea, int line);
///
/// This function sets the indentlevel in a range of lines.
///
void IndentLines(TextArea textArea, int begin, int end);
///
/// Finds the offset of the opening bracket in the block defined by offset skipping
/// brackets in strings and comments.
///
/// The document to search in.
/// The offset of an position in the block or the offset of the closing bracket.
/// The character for the opening bracket.
/// The character for the closing bracket.
/// Returns the offset of the opening bracket or -1 if no matching bracket was found.
int SearchBracketBackward(IDocument document, int offset, char openBracket, char closingBracket);
///
/// Finds the offset of the closing bracket in the block defined by offset skipping
/// brackets in strings and comments.
///
/// The document to search in.
/// The offset of an position in the block or the offset of the opening bracket.
/// The character for the opening bracket.
/// The character for the closing bracket.
/// Returns the offset of the closing bracket or -1 if no matching bracket was found.
int SearchBracketForward(IDocument document, int offset, char openBracket, char closingBracket);
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/DefaultHighlightingStrategy.cs
================================================
//
//
//
//
// $Revision: 3036 $
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
namespace ICSharpCode.TextEditor.Document
{
public class DefaultHighlightingStrategy : IHighlightingStrategyUsingRuleSets
{
string name;
List rules = new List();
Dictionary environmentColors = new Dictionary();
Dictionary properties = new Dictionary();
string[] extensions;
HighlightColor digitColor;
HighlightRuleSet defaultRuleSet = null;
public HighlightColor DigitColor {
get {
return digitColor;
}
set {
digitColor = value;
}
}
public IEnumerable> EnvironmentColors {
get {
return environmentColors;
}
}
protected void ImportSettingsFrom(DefaultHighlightingStrategy source)
{
if (source == null)
throw new ArgumentNullException("source");
properties = source.properties;
extensions = source.extensions;
digitColor = source.digitColor;
defaultRuleSet = source.defaultRuleSet;
name = source.name;
rules = source.rules;
environmentColors = source.environmentColors;
defaultTextColor = source.defaultTextColor;
}
public DefaultHighlightingStrategy() : this("Default")
{
}
public DefaultHighlightingStrategy(string name)
{
this.name = name;
digitColor = new HighlightColor(SystemColors.WindowText, false, false);
defaultTextColor = new HighlightColor(SystemColors.WindowText, false, false);
// set small 'default color environment'
environmentColors["Default"] = new HighlightBackground("WindowText", "Window", false, false);
environmentColors["Selection"] = new HighlightColor("HighlightText", "Highlight", false, false);
environmentColors["VRuler"] = new HighlightColor("ControlLight", "Window", false, false);
environmentColors["InvalidLines"] = new HighlightColor(Color.Red, false, false);
environmentColors["CaretMarker"] = new HighlightColor(Color.Yellow, false, false);
environmentColors["LineNumbers"] = new HighlightBackground("ControlDark", "Window", false, false);
environmentColors["FoldLine"] = new HighlightColor(Color.FromArgb(0x80, 0x80, 0x80), Color.Black, false, false);
environmentColors["FoldMarker"] = new HighlightColor(Color.FromArgb(0x80, 0x80, 0x80), Color.White, false, false);
environmentColors["SelectedFoldLine"] = new HighlightColor(Color.Black, false, false);
environmentColors["EOLMarkers"] = new HighlightColor("ControlLight", "Window", false, false);
environmentColors["SpaceMarkers"] = new HighlightColor("ControlLight", "Window", false, false);
environmentColors["TabMarkers"] = new HighlightColor("ControlLight", "Window", false, false);
}
public Dictionary Properties {
get {
return properties;
}
}
public string Name
{
get {
return name;
}
}
public string[] Extensions
{
set {
extensions = value;
}
get {
return extensions;
}
}
public List Rules {
get {
return rules;
}
}
public HighlightRuleSet FindHighlightRuleSet(string name)
{
foreach(HighlightRuleSet ruleSet in rules) {
if (ruleSet.Name == name) {
return ruleSet;
}
}
return null;
}
public void AddRuleSet(HighlightRuleSet aRuleSet)
{
HighlightRuleSet existing = FindHighlightRuleSet(aRuleSet.Name);
if (existing != null) {
existing.MergeFrom(aRuleSet);
} else {
rules.Add(aRuleSet);
}
}
public void ResolveReferences()
{
// Resolve references from Span definitions to RuleSets
ResolveRuleSetReferences();
// Resolve references from RuleSet defintitions to Highlighters defined in an external mode file
ResolveExternalReferences();
}
void ResolveRuleSetReferences()
{
foreach (HighlightRuleSet ruleSet in Rules) {
if (ruleSet.Name == null) {
defaultRuleSet = ruleSet;
}
foreach (Span aSpan in ruleSet.Spans) {
if (aSpan.Rule != null) {
bool found = false;
foreach (HighlightRuleSet refSet in Rules) {
if (refSet.Name == aSpan.Rule) {
found = true;
aSpan.RuleSet = refSet;
break;
}
}
if (!found) {
aSpan.RuleSet = null;
throw new HighlightingDefinitionInvalidException("The RuleSet " + aSpan.Rule + " could not be found in mode definition " + this.Name);
}
} else {
aSpan.RuleSet = null;
}
}
}
if (defaultRuleSet == null) {
throw new HighlightingDefinitionInvalidException("No default RuleSet is defined for mode definition " + this.Name);
}
}
void ResolveExternalReferences()
{
foreach (HighlightRuleSet ruleSet in Rules) {
ruleSet.Highlighter = this;
if (ruleSet.Reference != null) {
IHighlightingStrategy highlighter = HighlightingManager.Manager.FindHighlighter (ruleSet.Reference);
if (highlighter == null)
throw new HighlightingDefinitionInvalidException("The mode defintion " + ruleSet.Reference + " which is refered from the " + this.Name + " mode definition could not be found");
if (highlighter is IHighlightingStrategyUsingRuleSets)
ruleSet.Highlighter = (IHighlightingStrategyUsingRuleSets)highlighter;
else
throw new HighlightingDefinitionInvalidException("The mode defintion " + ruleSet.Reference + " which is refered from the " + this.Name + " mode definition does not implement IHighlightingStrategyUsingRuleSets");
}
}
}
// internal void SetDefaultColor(HighlightBackground color)
// {
// return (HighlightColor)environmentColors[name];
// defaultColor = color;
// }
HighlightColor defaultTextColor;
public HighlightColor DefaultTextColor {
get {
return defaultTextColor;
}
}
public void SetColorFor(string name, HighlightColor color)
{
if (name == "Default")
defaultTextColor = new HighlightColor(color.Color, color.Bold, color.Italic);
environmentColors[name] = color;
}
public HighlightColor GetColorFor(string name)
{
HighlightColor color;
if (environmentColors.TryGetValue(name, out color))
return color;
else
return defaultTextColor;
}
public HighlightColor GetColor(IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
{
return GetColor(defaultRuleSet, document, currentSegment, currentOffset, currentLength);
}
protected virtual HighlightColor GetColor(HighlightRuleSet ruleSet, IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
{
if (ruleSet != null) {
if (ruleSet.Reference != null) {
return ruleSet.Highlighter.GetColor(document, currentSegment, currentOffset, currentLength);
} else {
return (HighlightColor)ruleSet.KeyWords[document, currentSegment, currentOffset, currentLength];
}
}
return null;
}
public HighlightRuleSet GetRuleSet(Span aSpan)
{
if (aSpan == null) {
return this.defaultRuleSet;
} else {
if (aSpan.RuleSet != null)
{
if (aSpan.RuleSet.Reference != null) {
return aSpan.RuleSet.Highlighter.GetRuleSet(null);
} else {
return aSpan.RuleSet;
}
} else {
return null;
}
}
}
// Line state variable
protected LineSegment currentLine;
protected int currentLineNumber;
// Span stack state variable
protected SpanStack currentSpanStack;
public virtual void MarkTokens(IDocument document)
{
if (Rules.Count == 0) {
return;
}
int lineNumber = 0;
while (lineNumber < document.TotalNumberOfLines) {
LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);
if (lineNumber >= document.LineSegmentCollection.Count) { // may be, if the last line ends with a delimiter
break; // then the last line is not in the collection :)
}
currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? previousLine.HighlightSpanStack.Clone() : null);
if (currentSpanStack != null) {
while (!currentSpanStack.IsEmpty && currentSpanStack.Peek().StopEOL)
{
currentSpanStack.Pop();
}
if (currentSpanStack.IsEmpty) currentSpanStack = null;
}
currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];
if (currentLine.Length == -1) { // happens when buffer is empty !
return;
}
currentLineNumber = lineNumber;
List words = ParseLine(document);
// Alex: clear old words
if (currentLine.Words != null) {
currentLine.Words.Clear();
}
currentLine.Words = words;
currentLine.HighlightSpanStack = (currentSpanStack==null || currentSpanStack.IsEmpty) ? null : currentSpanStack;
++lineNumber;
}
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
document.CommitUpdate();
currentLine = null;
}
bool MarkTokensInLine(IDocument document, int lineNumber, ref bool spanChanged)
{
currentLineNumber = lineNumber;
bool processNextLine = false;
LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);
currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? previousLine.HighlightSpanStack.Clone() : null);
if (currentSpanStack != null) {
while (!currentSpanStack.IsEmpty && currentSpanStack.Peek().StopEOL) {
currentSpanStack.Pop();
}
if (currentSpanStack.IsEmpty) {
currentSpanStack = null;
}
}
currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];
if (currentLine.Length == -1) { // happens when buffer is empty !
return false;
}
List words = ParseLine(document);
if (currentSpanStack != null && currentSpanStack.IsEmpty) {
currentSpanStack = null;
}
// Check if the span state has changed, if so we must re-render the next line
// This check may seem utterly complicated but I didn't want to introduce any function calls
// or allocations here for perf reasons.
if(currentLine.HighlightSpanStack != currentSpanStack) {
if (currentLine.HighlightSpanStack == null) {
processNextLine = false;
foreach (Span sp in currentSpanStack) {
if (!sp.StopEOL) {
spanChanged = true;
processNextLine = true;
break;
}
}
} else if (currentSpanStack == null) {
processNextLine = false;
foreach (Span sp in currentLine.HighlightSpanStack) {
if (!sp.StopEOL) {
spanChanged = true;
processNextLine = true;
break;
}
}
} else {
SpanStack.Enumerator e1 = currentSpanStack.GetEnumerator();
SpanStack.Enumerator e2 = currentLine.HighlightSpanStack.GetEnumerator();
bool done = false;
while (!done) {
bool blockSpanIn1 = false;
while (e1.MoveNext()) {
if (!((Span)e1.Current).StopEOL) {
blockSpanIn1 = true;
break;
}
}
bool blockSpanIn2 = false;
while (e2.MoveNext()) {
if (!((Span)e2.Current).StopEOL) {
blockSpanIn2 = true;
break;
}
}
if (blockSpanIn1 || blockSpanIn2) {
if (blockSpanIn1 && blockSpanIn2) {
if (e1.Current != e2.Current) {
done = true;
processNextLine = true;
spanChanged = true;
}
} else {
spanChanged = true;
done = true;
processNextLine = true;
}
} else {
done = true;
processNextLine = false;
}
}
}
} else {
processNextLine = false;
}
//// Alex: remove old words
if (currentLine.Words!=null) currentLine.Words.Clear();
currentLine.Words = words;
currentLine.HighlightSpanStack = (currentSpanStack != null && !currentSpanStack.IsEmpty) ? currentSpanStack : null;
return processNextLine;
}
public virtual void MarkTokens(IDocument document, List inputLines)
{
if (Rules.Count == 0) {
return;
}
Dictionary processedLines = new Dictionary();
bool spanChanged = false;
int documentLineSegmentCount = document.LineSegmentCollection.Count;
foreach (LineSegment lineToProcess in inputLines) {
if (!processedLines.ContainsKey(lineToProcess)) {
int lineNumber = lineToProcess.LineNumber;
bool processNextLine = true;
if (lineNumber != -1) {
while (processNextLine && lineNumber < documentLineSegmentCount) {
processNextLine = MarkTokensInLine(document, lineNumber, ref spanChanged);
processedLines[currentLine] = true;
++lineNumber;
}
}
}
}
if (spanChanged || inputLines.Count > 20) {
// if the span was changed (more than inputLines lines had to be reevaluated)
// or if there are many lines in inputLines, it's faster to update the whole
// text area instead of many small segments
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
} else {
// document.Caret.ValidateCaretPos();
// document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, document.GetLineNumberForOffset(document.Caret.Offset)));
//
foreach (LineSegment lineToProcess in inputLines) {
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, lineToProcess.LineNumber));
}
}
document.CommitUpdate();
currentLine = null;
}
// Span state variables
protected bool inSpan;
protected Span activeSpan;
protected HighlightRuleSet activeRuleSet;
// Line scanning state variables
protected int currentOffset;
protected int currentLength;
void UpdateSpanStateVariables()
{
inSpan = (currentSpanStack != null && !currentSpanStack.IsEmpty);
activeSpan = inSpan ? currentSpanStack.Peek() : null;
activeRuleSet = GetRuleSet(activeSpan);
}
List ParseLine(IDocument document)
{
List words = new List();
HighlightColor markNext = null;
currentOffset = 0;
currentLength = 0;
UpdateSpanStateVariables();
int currentLineLength = currentLine.Length;
int currentLineOffset = currentLine.Offset;
for (int i = 0; i < currentLineLength; ++i) {
char ch = document.GetCharAt(currentLineOffset + i);
switch (ch) {
case '\n':
case '\r':
PushCurWord(document, ref markNext, words);
++currentOffset;
break;
case ' ':
PushCurWord(document, ref markNext, words);
if (activeSpan != null && activeSpan.Color.HasBackground) {
words.Add(new TextWord.SpaceTextWord(activeSpan.Color));
} else {
words.Add(TextWord.Space);
}
++currentOffset;
break;
case '\t':
PushCurWord(document, ref markNext, words);
if (activeSpan != null && activeSpan.Color.HasBackground) {
words.Add(new TextWord.TabTextWord(activeSpan.Color));
} else {
words.Add(TextWord.Tab);
}
++currentOffset;
break;
default:
{
// handle escape characters
char escapeCharacter = '\0';
if (activeSpan != null && activeSpan.EscapeCharacter != '\0') {
escapeCharacter = activeSpan.EscapeCharacter;
} else if (activeRuleSet != null) {
escapeCharacter = activeRuleSet.EscapeCharacter;
}
if (escapeCharacter != '\0' && escapeCharacter == ch) {
// we found the escape character
if (activeSpan != null && activeSpan.End != null && activeSpan.End.Length == 1
&& escapeCharacter == activeSpan.End[0])
{
// the escape character is a end-doubling escape character
// it may count as escape only when the next character is the escape, too
if (i + 1 < currentLineLength) {
if (document.GetCharAt(currentLineOffset + i + 1) == escapeCharacter) {
currentLength += 2;
PushCurWord(document, ref markNext, words);
++i;
continue;
}
}
} else {
// this is a normal \-style escape
++currentLength;
if (i + 1 < currentLineLength) {
++currentLength;
}
PushCurWord(document, ref markNext, words);
++i;
continue;
}
}
// highlight digits
if (!inSpan && (Char.IsDigit(ch) || (ch == '.' && i + 1 < currentLineLength && Char.IsDigit(document.GetCharAt(currentLineOffset + i + 1)))) && currentLength == 0) {
bool ishex = false;
bool isfloatingpoint = false;
if (ch == '0' && i + 1 < currentLineLength && Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'X') { // hex digits
const string hex = "0123456789ABCDEF";
++currentLength;
++i; // skip 'x'
++currentLength;
ishex = true;
while (i + 1 < currentLineLength && hex.IndexOf(Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1))) != -1) {
++i;
++currentLength;
}
} else {
++currentLength;
while (i + 1 < currentLineLength && Char.IsDigit(document.GetCharAt(currentLineOffset + i + 1))) {
++i;
++currentLength;
}
}
if (!ishex && i + 1 < currentLineLength && document.GetCharAt(currentLineOffset + i + 1) == '.') {
isfloatingpoint = true;
++i;
++currentLength;
while (i + 1 < currentLineLength && Char.IsDigit(document.GetCharAt(currentLineOffset + i + 1))) {
++i;
++currentLength;
}
}
if (i + 1 < currentLineLength && Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'E') {
isfloatingpoint = true;
++i;
++currentLength;
if (i + 1 < currentLineLength && (document.GetCharAt(currentLineOffset + i + 1) == '+' || document.GetCharAt(currentLine.Offset + i + 1) == '-')) {
++i;
++currentLength;
}
while (i + 1 < currentLine.Length && Char.IsDigit(document.GetCharAt(currentLineOffset + i + 1))) {
++i;
++currentLength;
}
}
if (i + 1 < currentLine.Length) {
char nextch = Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1));
if (nextch == 'F' || nextch == 'M' || nextch == 'D') {
isfloatingpoint = true;
++i;
++currentLength;
}
}
if (!isfloatingpoint) {
bool isunsigned = false;
if (i + 1 < currentLineLength && Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'U') {
++i;
++currentLength;
isunsigned = true;
}
if (i + 1 < currentLineLength && Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'L') {
++i;
++currentLength;
if (!isunsigned && i + 1 < currentLineLength && Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'U') {
++i;
++currentLength;
}
}
}
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, DigitColor, false));
currentOffset += currentLength;
currentLength = 0;
continue;
}
// Check for SPAN ENDs
if (inSpan) {
if (activeSpan.End != null && activeSpan.End.Length > 0) {
if (MatchExpr(currentLine, activeSpan.End, i, document, activeSpan.IgnoreCase)) {
PushCurWord(document, ref markNext, words);
string regex = GetRegString(currentLine, activeSpan.End, i, document);
currentLength += regex.Length;
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, activeSpan.EndColor, false));
currentOffset += currentLength;
currentLength = 0;
i += regex.Length - 1;
currentSpanStack.Pop();
UpdateSpanStateVariables();
continue;
}
}
}
// check for SPAN BEGIN
if (activeRuleSet != null) {
foreach (Span span in activeRuleSet.Spans) {
if ((!span.IsBeginSingleWord || currentLength == 0)
&& (!span.IsBeginStartOfLine.HasValue || span.IsBeginStartOfLine.Value == (currentLength == 0 && words.TrueForAll(delegate(TextWord textWord) { return textWord.Type != TextWordType.Word; })))
&& MatchExpr(currentLine, span.Begin, i, document, activeRuleSet.IgnoreCase)) {
PushCurWord(document, ref markNext, words);
string regex = GetRegString(currentLine, span.Begin, i, document);
if (!OverrideSpan(regex, document, words, span, ref i)) {
currentLength += regex.Length;
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, span.BeginColor, false));
currentOffset += currentLength;
currentLength = 0;
i += regex.Length - 1;
if (currentSpanStack == null) {
currentSpanStack = new SpanStack();
}
currentSpanStack.Push(span);
span.IgnoreCase = activeRuleSet.IgnoreCase;
UpdateSpanStateVariables();
}
goto skip;
}
}
}
// check if the char is a delimiter
if (activeRuleSet != null && (int)ch < 256 && activeRuleSet.Delimiters[(int)ch]) {
PushCurWord(document, ref markNext, words);
if (currentOffset + currentLength +1 < currentLine.Length) {
++currentLength;
PushCurWord(document, ref markNext, words);
goto skip;
}
}
++currentLength;
skip: continue;
}
}
}
PushCurWord(document, ref markNext, words);
OnParsedLine(document, currentLine, words);
return words;
}
protected virtual void OnParsedLine(IDocument document, LineSegment currentLine, List words)
{
}
protected virtual bool OverrideSpan(string spanBegin, IDocument document, List words, Span span, ref int lineOffset)
{
return false;
}
///
/// pushes the curWord string on the word list, with the
/// correct color.
///
void PushCurWord(IDocument document, ref HighlightColor markNext, List words)
{
// Svante Lidman : Need to look through the next prev logic.
if (currentLength > 0) {
if (words.Count > 0 && activeRuleSet != null) {
TextWord prevWord = null;
int pInd = words.Count - 1;
while (pInd >= 0) {
if (!((TextWord)words[pInd]).IsWhiteSpace) {
prevWord = (TextWord)words[pInd];
if (prevWord.HasDefaultColor) {
PrevMarker marker = (PrevMarker)activeRuleSet.PrevMarkers[document, currentLine, currentOffset, currentLength];
if (marker != null) {
prevWord.SyntaxColor = marker.Color;
// document.Caret.ValidateCaretPos();
// document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, document.GetLineNumberForOffset(document.Caret.Offset)));
}
}
break;
}
pInd--;
}
}
if (inSpan) {
HighlightColor c = null;
bool hasDefaultColor = true;
if (activeSpan.Rule == null) {
c = activeSpan.Color;
} else {
c = GetColor(activeRuleSet, document, currentLine, currentOffset, currentLength);
hasDefaultColor = false;
}
if (c == null) {
c = activeSpan.Color;
if (c.Color == Color.Transparent) {
c = this.DefaultTextColor;
}
hasDefaultColor = true;
}
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, markNext != null ? markNext : c, hasDefaultColor));
} else {
HighlightColor c = markNext != null ? markNext : GetColor(activeRuleSet, document, currentLine, currentOffset, currentLength);
if (c == null) {
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, this.DefaultTextColor, true));
} else {
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, c, false));
}
}
if (activeRuleSet != null) {
NextMarker nextMarker = (NextMarker)activeRuleSet.NextMarkers[document, currentLine, currentOffset, currentLength];
if (nextMarker != null) {
if (nextMarker.MarkMarker && words.Count > 0) {
TextWord prevword = ((TextWord)words[words.Count - 1]);
prevword.SyntaxColor = nextMarker.Color;
}
markNext = nextMarker.Color;
} else {
markNext = null;
}
}
currentOffset += currentLength;
currentLength = 0;
}
}
#region Matching
///
/// get the string, which matches the regular expression expr,
/// in string s2 at index
///
static string GetRegString(LineSegment lineSegment, char[] expr, int index, IDocument document)
{
int j = 0;
StringBuilder regexpr = new StringBuilder();
for (int i = 0; i < expr.Length; ++i, ++j) {
if (index + j >= lineSegment.Length)
break;
switch (expr[i]) {
case '@': // "special" meaning
++i;
switch (expr[i]) {
case '!': // don't match the following expression
StringBuilder whatmatch = new StringBuilder();
++i;
while (i < expr.Length && expr[i] != '@') {
whatmatch.Append(expr[i++]);
}
break;
case '@': // matches @
regexpr.Append(document.GetCharAt(lineSegment.Offset + index + j));
break;
}
break;
default:
if (expr[i] != document.GetCharAt(lineSegment.Offset + index + j)) {
return regexpr.ToString();
}
regexpr.Append(document.GetCharAt(lineSegment.Offset + index + j));
break;
}
}
return regexpr.ToString();
}
///
/// returns true, if the get the string s2 at index matches the expression expr
///
static bool MatchExpr(LineSegment lineSegment, char[] expr, int index, IDocument document, bool ignoreCase)
{
for (int i = 0, j = 0; i < expr.Length; ++i, ++j) {
switch (expr[i]) {
case '@': // "special" meaning
++i;
if (i < expr.Length) {
switch (expr[i]) {
case 'C': // match whitespace or punctuation
if (index + j == lineSegment.Offset || index + j >= lineSegment.Offset + lineSegment.Length) {
// nothing (EOL or SOL)
} else {
char ch = document.GetCharAt(lineSegment.Offset + index + j);
if (!Char.IsWhiteSpace(ch) && !Char.IsPunctuation(ch)) {
return false;
}
}
break;
case '!': // don't match the following expression
{
StringBuilder whatmatch = new StringBuilder();
++i;
while (i < expr.Length && expr[i] != '@') {
whatmatch.Append(expr[i++]);
}
if (lineSegment.Offset + index + j + whatmatch.Length < document.TextLength) {
int k = 0;
for (; k < whatmatch.Length; ++k) {
char docChar = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j + k)) : document.GetCharAt(lineSegment.Offset + index + j + k);
char spanChar = ignoreCase ? Char.ToUpperInvariant(whatmatch[k]) : whatmatch[k];
if (docChar != spanChar) {
break;
}
}
if (k >= whatmatch.Length) {
return false;
}
}
// --j;
break;
}
case '-': // don't match the expression before
{
StringBuilder whatmatch = new StringBuilder();
++i;
while (i < expr.Length && expr[i] != '@') {
whatmatch.Append(expr[i++]);
}
if (index - whatmatch.Length >= 0) {
int k = 0;
for (; k < whatmatch.Length; ++k) {
char docChar = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k)) : document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k);
char spanChar = ignoreCase ? Char.ToUpperInvariant(whatmatch[k]) : whatmatch[k];
if (docChar != spanChar)
break;
}
if (k >= whatmatch.Length) {
return false;
}
}
// --j;
break;
}
case '@': // matches @
if (index + j >= lineSegment.Length || '@' != document.GetCharAt(lineSegment.Offset + index + j)) {
return false;
}
break;
}
}
break;
default:
{
if (index + j >= lineSegment.Length) {
return false;
}
char docChar = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j)) : document.GetCharAt(lineSegment.Offset + index + j);
char spanChar = ignoreCase ? Char.ToUpperInvariant(expr[i]) : expr[i];
if (docChar != spanChar) {
return false;
}
break;
}
}
}
return true;
}
#endregion
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/FontContainer.cs
================================================
//
//
//
//
// $Revision: 3358 $
//
using System;
using System.Drawing;
namespace ICSharpCode.TextEditor.Document
{
///
/// This class is used to generate bold, italic and bold/italic fonts out
/// of a base font.
///
public class FontContainer
{
Font defaultFont;
Font regularfont, boldfont, italicfont, bolditalicfont;
///
/// The scaled, regular version of the base font
///
public Font RegularFont {
get {
return regularfont;
}
}
///
/// The scaled, bold version of the base font
///
public Font BoldFont {
get {
return boldfont;
}
}
///
/// The scaled, italic version of the base font
///
public Font ItalicFont {
get {
return italicfont;
}
}
///
/// The scaled, bold/italic version of the base font
///
public Font BoldItalicFont {
get {
return bolditalicfont;
}
}
static float twipsPerPixelY;
public static float TwipsPerPixelY {
get {
if (twipsPerPixelY == 0) {
using (Bitmap bmp = new Bitmap(1,1)) {
using (Graphics g = Graphics.FromImage(bmp)) {
twipsPerPixelY = 1440 / g.DpiY;
}
}
}
return twipsPerPixelY;
}
}
///
/// The base font
///
public Font DefaultFont {
get {
return defaultFont;
}
set {
// 1440 twips is one inch
float pixelSize = (float)Math.Round(value.SizeInPoints * 20 / TwipsPerPixelY);
defaultFont = value;
regularfont = new Font(value.FontFamily, pixelSize * TwipsPerPixelY / 20f, FontStyle.Regular);
boldfont = new Font(regularfont, FontStyle.Bold);
italicfont = new Font(regularfont, FontStyle.Italic);
bolditalicfont = new Font(regularfont, FontStyle.Bold | FontStyle.Italic);
}
}
public static Font ParseFont(string font)
{
string[] descr = font.Split(new char[]{',', '='});
return new Font(descr[1], Single.Parse(descr[3]));
}
public FontContainer(Font defaultFont)
{
this.DefaultFont = defaultFont;
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/HighlightBackground.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
using System.Drawing;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
///
/// Extens the highlighting color with a background image.
///
public class HighlightBackground : HighlightColor
{
Image backgroundImage;
///
/// The image used as background
///
public Image BackgroundImage {
get {
return backgroundImage;
}
}
///
/// Creates a new instance of
///
public HighlightBackground(XmlElement el) : base(el)
{
if (el.Attributes["image"] != null) {
backgroundImage = new Bitmap(el.Attributes["image"].InnerText);
}
}
///
/// Creates a new instance of
///
public HighlightBackground(Color color, Color backgroundcolor, bool bold, bool italic) : base(color, backgroundcolor, bold, italic)
{
}
public HighlightBackground(string systemColor, string systemBackgroundColor, bool bold, bool italic) : base(systemColor, systemBackgroundColor, bold, italic)
{
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/HighlightColor.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
///
/// A color used for highlighting
///
public class HighlightColor
{
bool systemColor = false;
string systemColorName = null;
bool systemBgColor = false;
string systemBgColorName = null;
Color color;
Color backgroundcolor = System.Drawing.Color.WhiteSmoke;
bool bold = false;
bool italic = false;
bool hasForeground = false;
bool hasBackground = false;
public bool HasForeground {
get {
return hasForeground;
}
}
public bool HasBackground {
get {
return hasBackground;
}
}
///
/// If true the font will be displayed bold style
///
public bool Bold {
get {
return bold;
}
}
///
/// If true the font will be displayed italic style
///
public bool Italic {
get {
return italic;
}
}
///
/// The background color used
///
public Color BackgroundColor {
get {
if (!systemBgColor) {
return backgroundcolor;
}
return ParseColorString(systemBgColorName);
}
}
///
/// The foreground color used
///
public Color Color {
get {
if (!systemColor) {
return color;
}
return ParseColorString(systemColorName);
}
}
///
/// The font used
///
public Font GetFont(FontContainer fontContainer)
{
if (Bold) {
return Italic ? fontContainer.BoldItalicFont : fontContainer.BoldFont;
}
return Italic ? fontContainer.ItalicFont : fontContainer.RegularFont;
}
Color ParseColorString(string colorName)
{
string[] cNames = colorName.Split('*');
PropertyInfo myPropInfo = typeof(System.Drawing.SystemColors).GetProperty(cNames[0], BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.Static);
Color c = (Color)myPropInfo.GetValue(null, null);
if (cNames.Length == 2) {
// hack : can't figure out how to parse doubles with '.' (culture info might set the '.' to ',')
double factor = Double.Parse(cNames[1]) / 100;
c = Color.FromArgb((int)((double)c.R * factor), (int)((double)c.G * factor), (int)((double)c.B * factor));
}
return c;
}
///
/// Creates a new instance of
///
public HighlightColor(XmlElement el)
{
Debug.Assert(el != null, "ICSharpCode.TextEditor.Document.SyntaxColor(XmlElement el) : el == null");
if (el.Attributes["bold"] != null) {
bold = Boolean.Parse(el.Attributes["bold"].InnerText);
}
if (el.Attributes["italic"] != null) {
italic = Boolean.Parse(el.Attributes["italic"].InnerText);
}
if (el.Attributes["color"] != null) {
string c = el.Attributes["color"].InnerText;
if (c[0] == '#') {
color = ParseColor(c);
} else if (c.StartsWith("SystemColors.")) {
systemColor = true;
systemColorName = c.Substring("SystemColors.".Length);
} else {
color = (Color)(Color.GetType()).InvokeMember(c, BindingFlags.GetProperty, null, Color, new object[0]);
}
hasForeground = true;
} else {
color = Color.Transparent; // to set it to the default value.
}
if (el.Attributes["bgcolor"] != null) {
string c = el.Attributes["bgcolor"].InnerText;
if (c[0] == '#') {
backgroundcolor = ParseColor(c);
} else if (c.StartsWith("SystemColors.")) {
systemBgColor = true;
systemBgColorName = c.Substring("SystemColors.".Length);
} else {
backgroundcolor = (Color)(Color.GetType()).InvokeMember(c, BindingFlags.GetProperty, null, Color, new object[0]);
}
hasBackground = true;
}
}
///
/// Creates a new instance of
///
public HighlightColor(XmlElement el, HighlightColor defaultColor)
{
Debug.Assert(el != null, "ICSharpCode.TextEditor.Document.SyntaxColor(XmlElement el) : el == null");
if (el.Attributes["bold"] != null) {
bold = Boolean.Parse(el.Attributes["bold"].InnerText);
} else {
bold = defaultColor.Bold;
}
if (el.Attributes["italic"] != null) {
italic = Boolean.Parse(el.Attributes["italic"].InnerText);
} else {
italic = defaultColor.Italic;
}
if (el.Attributes["color"] != null) {
string c = el.Attributes["color"].InnerText;
if (c[0] == '#') {
color = ParseColor(c);
} else if (c.StartsWith("SystemColors.")) {
systemColor = true;
systemColorName = c.Substring("SystemColors.".Length);
} else {
color = (Color)(Color.GetType()).InvokeMember(c, BindingFlags.GetProperty, null, Color, new object[0]);
}
hasForeground = true;
} else {
color = defaultColor.color;
}
if (el.Attributes["bgcolor"] != null) {
string c = el.Attributes["bgcolor"].InnerText;
if (c[0] == '#') {
backgroundcolor = ParseColor(c);
} else if (c.StartsWith("SystemColors.")) {
systemBgColor = true;
systemBgColorName = c.Substring("SystemColors.".Length);
} else {
backgroundcolor = (Color)(Color.GetType()).InvokeMember(c, BindingFlags.GetProperty, null, Color, new object[0]);
}
hasBackground = true;
} else {
backgroundcolor = defaultColor.BackgroundColor;
}
}
///
/// Creates a new instance of
///
public HighlightColor(Color color, bool bold, bool italic)
{
hasForeground = true;
this.color = color;
this.bold = bold;
this.italic = italic;
}
///
/// Creates a new instance of
///
public HighlightColor(Color color, Color backgroundcolor, bool bold, bool italic)
{
hasForeground = true;
hasBackground = true;
this.color = color;
this.backgroundcolor = backgroundcolor;
this.bold = bold;
this.italic = italic;
}
///
/// Creates a new instance of
///
public HighlightColor(string systemColor, string systemBackgroundColor, bool bold, bool italic)
{
hasForeground = true;
hasBackground = true;
this.systemColor = true;
systemColorName = systemColor;
systemBgColor = true;
systemBgColorName = systemBackgroundColor;
this.bold = bold;
this.italic = italic;
}
static Color ParseColor(string c)
{
int a = 255;
int offset = 0;
if (c.Length > 7) {
offset = 2;
a = Int32.Parse(c.Substring(1,2), NumberStyles.HexNumber);
}
int r = Int32.Parse(c.Substring(1 + offset,2), NumberStyles.HexNumber);
int g = Int32.Parse(c.Substring(3 + offset,2), NumberStyles.HexNumber);
int b = Int32.Parse(c.Substring(5 + offset,2), NumberStyles.HexNumber);
return Color.FromArgb(a, r, g, b);
}
///
/// Converts a instance to string (for debug purposes)
///
public override string ToString()
{
return "[HighlightColor: Bold = " + Bold +
", Italic = " + Italic +
", Color = " + Color +
", BackgroundColor = " + BackgroundColor + "]";
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/HighlightInfo.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
namespace ICSharpCode.TextEditor.Document
{
public class HighlightInfo
{
public bool BlockSpanOn = false;
public bool Span = false;
public Span CurSpan = null;
public HighlightInfo(Span curSpan, bool span, bool blockSpanOn)
{
this.CurSpan = curSpan;
this.Span = span;
this.BlockSpanOn = blockSpanOn;
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/HighlightRuleSet.cs
================================================
//
//
//
//
// $Revision: 3036 $
//
using System;
using System.Collections;
using System.Xml;
using ICSharpCode.TextEditor.Util;
namespace ICSharpCode.TextEditor.Document
{
public class HighlightRuleSet
{
LookupTable keyWords;
ArrayList spans = new ArrayList();
LookupTable prevMarkers;
LookupTable nextMarkers;
char escapeCharacter;
bool ignoreCase = false;
string name = null;
bool[] delimiters = new bool[256];
string reference = null;
public ArrayList Spans {
get {
return spans;
}
}
internal IHighlightingStrategyUsingRuleSets Highlighter;
public LookupTable KeyWords {
get {
return keyWords;
}
}
public LookupTable PrevMarkers {
get {
return prevMarkers;
}
}
public LookupTable NextMarkers {
get {
return nextMarkers;
}
}
public bool[] Delimiters {
get {
return delimiters;
}
}
public char EscapeCharacter {
get {
return escapeCharacter;
}
}
public bool IgnoreCase {
get {
return ignoreCase;
}
}
public string Name {
get {
return name;
}
set {
name = value;
}
}
public string Reference {
get {
return reference;
}
}
public HighlightRuleSet()
{
keyWords = new LookupTable(false);
prevMarkers = new LookupTable(false);
nextMarkers = new LookupTable(false);
}
public HighlightRuleSet(XmlElement el)
{
XmlNodeList nodes;
if (el.Attributes["name"] != null) {
Name = el.Attributes["name"].InnerText;
}
if (el.HasAttribute("escapecharacter")) {
escapeCharacter = el.GetAttribute("escapecharacter")[0];
}
if (el.Attributes["reference"] != null) {
reference = el.Attributes["reference"].InnerText;
}
if (el.Attributes["ignorecase"] != null) {
ignoreCase = Boolean.Parse(el.Attributes["ignorecase"].InnerText);
}
for (int i = 0; i < Delimiters.Length; ++i) {
delimiters[i] = false;
}
if (el["Delimiters"] != null) {
string delimiterString = el["Delimiters"].InnerText;
foreach (char ch in delimiterString) {
delimiters[(int)ch] = true;
}
}
// Spans = new LookupTable(!IgnoreCase);
keyWords = new LookupTable(!IgnoreCase);
prevMarkers = new LookupTable(!IgnoreCase);
nextMarkers = new LookupTable(!IgnoreCase);
nodes = el.GetElementsByTagName("KeyWords");
foreach (XmlElement el2 in nodes) {
HighlightColor color = new HighlightColor(el2);
XmlNodeList keys = el2.GetElementsByTagName("Key");
foreach (XmlElement node in keys) {
keyWords[node.Attributes["word"].InnerText] = color;
}
}
nodes = el.GetElementsByTagName("Span");
foreach (XmlElement el2 in nodes) {
Spans.Add(new Span(el2));
/*
Span span = new Span(el2);
Spans[span.Begin] = span;*/
}
nodes = el.GetElementsByTagName("MarkPrevious");
foreach (XmlElement el2 in nodes) {
PrevMarker prev = new PrevMarker(el2);
prevMarkers[prev.What] = prev;
}
nodes = el.GetElementsByTagName("MarkFollowing");
foreach (XmlElement el2 in nodes) {
NextMarker next = new NextMarker(el2);
nextMarkers[next.What] = next;
}
}
///
/// Merges spans etc. from the other rule set into this rule set.
///
public void MergeFrom(HighlightRuleSet ruleSet)
{
for (int i = 0; i < delimiters.Length; i++) {
delimiters[i] |= ruleSet.delimiters[i];
}
// insert merged spans in front of old spans
ArrayList oldSpans = spans;
spans = (ArrayList)ruleSet.spans.Clone();
spans.AddRange(oldSpans);
//keyWords.MergeFrom(ruleSet.keyWords);
//prevMarkers.MergeFrom(ruleSet.prevMarkers);
//nextMarkers.MergeFrom(ruleSet.nextMarkers);
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/HighlightingColorNotFoundException.cs
================================================
//
//
//
//
// $Revision: 1624 $
//
using System;
using System.Runtime.Serialization;
namespace ICSharpCode.TextEditor.Document
{
[Serializable()]
public class HighlightingColorNotFoundException : Exception
{
public HighlightingColorNotFoundException() : base()
{
}
public HighlightingColorNotFoundException(string message) : base(message)
{
}
public HighlightingColorNotFoundException(string message, Exception innerException) : base(message, innerException)
{
}
protected HighlightingColorNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/HighlightingDefinitionInvalidException.cs
================================================
//
//
//
//
// $Revision: 2533 $
//
using System;
using System.Runtime.Serialization;
namespace ICSharpCode.TextEditor.Document
{
///
/// Indicates that the highlighting definition that was tried to load was invalid.
/// You get this exception only once per highlighting definition, after that the definition
/// is replaced with the default highlighter.
///
[Serializable()]
public class HighlightingDefinitionInvalidException : Exception
{
public HighlightingDefinitionInvalidException() : base()
{
}
public HighlightingDefinitionInvalidException(string message) : base(message)
{
}
public HighlightingDefinitionInvalidException(string message, Exception innerException) : base(message, innerException)
{
}
protected HighlightingDefinitionInvalidException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/HighlightingDefinitionParser.cs
================================================
//
//
//
//
// $Revision: 2533 $
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Schema;
namespace ICSharpCode.TextEditor.Document
{
public static class HighlightingDefinitionParser
{
public static DefaultHighlightingStrategy Parse(SyntaxMode syntaxMode, XmlReader xmlReader)
{
return Parse(null, syntaxMode, xmlReader);
}
public static DefaultHighlightingStrategy Parse(DefaultHighlightingStrategy highlighter, SyntaxMode syntaxMode, XmlReader xmlReader)
{
if (syntaxMode == null)
throw new ArgumentNullException("syntaxMode");
if (xmlReader == null)
throw new ArgumentNullException("xmlTextReader");
try {
List errors = null;
XmlReaderSettings settings = new XmlReaderSettings();
Stream shemaStream = typeof(HighlightingDefinitionParser).Assembly.GetManifestResourceStream("ICSharpCode.TextEditor.Resources.Mode.xsd");
settings.Schemas.Add("", new XmlTextReader(shemaStream));
settings.Schemas.ValidationEventHandler += delegate(object sender, ValidationEventArgs args) {
if (errors == null) {
errors = new List();
}
errors.Add(args);
};
settings.ValidationType = ValidationType.Schema;
XmlReader validatingReader = XmlReader.Create(xmlReader, settings);
XmlDocument doc = new XmlDocument();
doc.Load(validatingReader);
if (highlighter == null)
highlighter = new DefaultHighlightingStrategy(doc.DocumentElement.Attributes["name"].InnerText);
if (doc.DocumentElement.HasAttribute("extends")) {
KeyValuePair entry = HighlightingManager.Manager.FindHighlighterEntry(doc.DocumentElement.GetAttribute("extends"));
if (entry.Key == null) {
throw new HighlightingDefinitionInvalidException("Cannot find referenced highlighting source " + doc.DocumentElement.GetAttribute("extends"));
} else {
highlighter = Parse(highlighter, entry.Key, entry.Value.GetSyntaxModeFile(entry.Key));
if (highlighter == null) return null;
}
}
if (doc.DocumentElement.HasAttribute("extensions")) {
highlighter.Extensions = doc.DocumentElement.GetAttribute("extensions").Split(new char[] { ';', '|' });
}
XmlElement environment = doc.DocumentElement["Environment"];
if (environment != null) {
foreach (XmlNode node in environment.ChildNodes) {
if (node is XmlElement) {
XmlElement el = (XmlElement)node;
if (el.Name == "Custom") {
highlighter.SetColorFor(el.GetAttribute("name"), el.HasAttribute("bgcolor") ? new HighlightBackground(el) : new HighlightColor(el));
} else {
highlighter.SetColorFor(el.Name, el.HasAttribute("bgcolor") ? new HighlightBackground(el) : new HighlightColor(el));
}
}
}
}
// parse properties
if (doc.DocumentElement["Properties"]!= null) {
foreach (XmlElement propertyElement in doc.DocumentElement["Properties"].ChildNodes) {
highlighter.Properties[propertyElement.Attributes["name"].InnerText] = propertyElement.Attributes["value"].InnerText;
}
}
if (doc.DocumentElement["Digits"]!= null) {
highlighter.DigitColor = new HighlightColor(doc.DocumentElement["Digits"]);
}
XmlNodeList nodes = doc.DocumentElement.GetElementsByTagName("RuleSet");
foreach (XmlElement element in nodes) {
highlighter.AddRuleSet(new HighlightRuleSet(element));
}
xmlReader.Close();
if (errors != null) {
StringBuilder msg = new StringBuilder();
foreach (ValidationEventArgs args in errors) {
msg.AppendLine(args.Message);
}
throw new HighlightingDefinitionInvalidException(msg.ToString());
} else {
return highlighter;
}
} catch (Exception e) {
throw new HighlightingDefinitionInvalidException("Could not load mode definition file '" + syntaxMode.FileName + "'.\n", e);
}
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/HighlightingManager.cs
================================================
//
//
//
//
// $Revision: 3209 $
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
namespace ICSharpCode.TextEditor.Document
{
public class HighlightingManager
{
ArrayList syntaxModeFileProviders = new ArrayList();
static HighlightingManager highlightingManager;
// hash table from extension name to highlighting definition,
// OR from extension name to Pair SyntaxMode,ISyntaxModeFileProvider
Hashtable highlightingDefs = new Hashtable();
Hashtable extensionsToName = new Hashtable();
public Hashtable HighlightingDefinitions {
get {
return highlightingDefs;
}
}
public static HighlightingManager Manager {
get {
return highlightingManager;
}
}
static HighlightingManager()
{
highlightingManager = new HighlightingManager();
highlightingManager.AddSyntaxModeFileProvider(new ResourceSyntaxModeProvider());
}
public HighlightingManager()
{
CreateDefaultHighlightingStrategy();
}
public void AddSyntaxModeFileProvider(ISyntaxModeFileProvider syntaxModeFileProvider)
{
foreach (SyntaxMode syntaxMode in syntaxModeFileProvider.SyntaxModes) {
highlightingDefs[syntaxMode.Name] = new DictionaryEntry(syntaxMode, syntaxModeFileProvider);
foreach (string extension in syntaxMode.Extensions) {
extensionsToName[extension.ToUpperInvariant()] = syntaxMode.Name;
}
}
if (!syntaxModeFileProviders.Contains(syntaxModeFileProvider)) {
syntaxModeFileProviders.Add(syntaxModeFileProvider);
}
}
public void AddHighlightingStrategy(IHighlightingStrategy highlightingStrategy)
{
highlightingDefs[highlightingStrategy.Name] = highlightingStrategy;
foreach (string extension in highlightingStrategy.Extensions)
{
extensionsToName[extension.ToUpperInvariant()] = highlightingStrategy.Name;
}
}
public void ReloadSyntaxModes()
{
highlightingDefs.Clear();
extensionsToName.Clear();
CreateDefaultHighlightingStrategy();
foreach (ISyntaxModeFileProvider provider in syntaxModeFileProviders) {
provider.UpdateSyntaxModeList();
AddSyntaxModeFileProvider(provider);
}
OnReloadSyntaxHighlighting(EventArgs.Empty);
}
void CreateDefaultHighlightingStrategy()
{
DefaultHighlightingStrategy defaultHighlightingStrategy = new DefaultHighlightingStrategy();
defaultHighlightingStrategy.Extensions = new string[] {};
defaultHighlightingStrategy.Rules.Add(new HighlightRuleSet());
highlightingDefs["Default"] = defaultHighlightingStrategy;
}
IHighlightingStrategy LoadDefinition(DictionaryEntry entry)
{
SyntaxMode syntaxMode = (SyntaxMode)entry.Key;
ISyntaxModeFileProvider syntaxModeFileProvider = (ISyntaxModeFileProvider)entry.Value;
DefaultHighlightingStrategy highlightingStrategy = null;
try {
var reader = syntaxModeFileProvider.GetSyntaxModeFile(syntaxMode);
if (reader == null)
throw new HighlightingDefinitionInvalidException("Could not get syntax mode file for " + syntaxMode.Name);
highlightingStrategy = HighlightingDefinitionParser.Parse(syntaxMode, reader);
if (highlightingStrategy.Name != syntaxMode.Name) {
throw new HighlightingDefinitionInvalidException("The name specified in the .xshd '" + highlightingStrategy.Name + "' must be equal the syntax mode name '" + syntaxMode.Name + "'");
}
} finally {
if (highlightingStrategy == null) {
highlightingStrategy = DefaultHighlighting;
}
highlightingDefs[syntaxMode.Name] = highlightingStrategy;
highlightingStrategy.ResolveReferences();
}
return highlightingStrategy;
}
public DefaultHighlightingStrategy DefaultHighlighting {
get {
return (DefaultHighlightingStrategy)highlightingDefs["Default"];
}
}
internal KeyValuePair FindHighlighterEntry(string name)
{
foreach (ISyntaxModeFileProvider provider in syntaxModeFileProviders) {
foreach (SyntaxMode mode in provider.SyntaxModes) {
if (mode.Name == name) {
return new KeyValuePair(mode, provider);
}
}
}
return new KeyValuePair(null, null);
}
public IHighlightingStrategy FindHighlighter(string name)
{
object def = highlightingDefs[name];
if (def is DictionaryEntry) {
return LoadDefinition((DictionaryEntry)def);
}
return def == null ? DefaultHighlighting : (IHighlightingStrategy)def;
}
public IHighlightingStrategy FindHighlighterForFile(string fileName)
{
string highlighterName = (string)extensionsToName[Path.GetExtension(fileName).ToUpperInvariant()];
if (highlighterName != null) {
object def = highlightingDefs[highlighterName];
if (def is DictionaryEntry) {
return LoadDefinition((DictionaryEntry)def);
}
return def == null ? DefaultHighlighting : (IHighlightingStrategy)def;
} else {
return DefaultHighlighting;
}
}
protected virtual void OnReloadSyntaxHighlighting(EventArgs e)
{
if (ReloadSyntaxHighlighting != null) {
ReloadSyntaxHighlighting(this, e);
}
}
public event EventHandler ReloadSyntaxHighlighting;
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/HighlightingStrategyFactory.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
namespace ICSharpCode.TextEditor.Document
{
public class HighlightingStrategyFactory
{
public static IHighlightingStrategy CreateHighlightingStrategy()
{
return (IHighlightingStrategy)HighlightingManager.Manager.HighlightingDefinitions["Default"];
}
public static IHighlightingStrategy CreateHighlightingStrategy(string name)
{
IHighlightingStrategy highlightingStrategy = HighlightingManager.Manager.FindHighlighter(name);
if (highlightingStrategy == null) {
return CreateHighlightingStrategy();
}
return highlightingStrategy;
}
public static IHighlightingStrategy CreateHighlightingStrategyForFile(string fileName)
{
IHighlightingStrategy highlightingStrategy = HighlightingManager.Manager.FindHighlighterForFile(fileName);
if (highlightingStrategy == null) {
return CreateHighlightingStrategy();
}
return highlightingStrategy;
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/IHighlightingStrategy.cs
================================================
//
//
//
//
// $Revision: 3037 $
//
using System;
using System.Collections.Generic;
namespace ICSharpCode.TextEditor.Document
{
///
/// A highlighting strategy for a buffer.
///
public interface IHighlightingStrategy
{
///
/// The name of the highlighting strategy, must be unique
///
string Name {
get;
}
///
/// The file extenstions on which this highlighting strategy gets
/// used
///
string[] Extensions {
get;
}
Dictionary Properties {
get;
}
// returns special color. (BackGround Color, Cursor Color and so on)
///
/// Gets the color of an Environment element.
///
HighlightColor GetColorFor(string name);
///
/// Used internally, do not call
///
void MarkTokens(IDocument document, List lines);
///
/// Used internally, do not call
///
void MarkTokens(IDocument document);
}
public interface IHighlightingStrategyUsingRuleSets : IHighlightingStrategy
{
///
/// Used internally, do not call
///
HighlightRuleSet GetRuleSet(Span span);
///
/// Used internally, do not call
///
HighlightColor GetColor(IDocument document, LineSegment keyWord, int index, int length);
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/NextMarker.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
///
/// Used for mark next token
///
public class NextMarker
{
string what;
HighlightColor color;
bool markMarker = false;
///
/// String value to indicate to mark next token
///
public string What {
get {
return what;
}
}
///
/// Color for marking next token
///
public HighlightColor Color {
get {
return color;
}
}
///
/// If true the indication text will be marked with the same color
/// too
///
public bool MarkMarker {
get {
return markMarker;
}
}
///
/// Creates a new instance of
///
public NextMarker(XmlElement mark)
{
color = new HighlightColor(mark);
what = mark.InnerText;
if (mark.Attributes["markmarker"] != null) {
markMarker = Boolean.Parse(mark.Attributes["markmarker"].InnerText);
}
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/PrevMarker.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
///
/// Used for mark previous token
///
public class PrevMarker
{
string what;
HighlightColor color;
bool markMarker = false;
///
/// String value to indicate to mark previous token
///
public string What {
get {
return what;
}
}
///
/// Color for marking previous token
///
public HighlightColor Color {
get {
return color;
}
}
///
/// If true the indication text will be marked with the same color
/// too
///
public bool MarkMarker {
get {
return markMarker;
}
}
///
/// Creates a new instance of
///
public PrevMarker(XmlElement mark)
{
color = new HighlightColor(mark);
what = mark.InnerText;
if (mark.Attributes["markmarker"] != null) {
markMarker = Boolean.Parse(mark.Attributes["markmarker"].InnerText);
}
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/Span.cs
================================================
//
//
//
//
// $Revision: 2115 $
//
using System;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
public sealed class Span
{
bool stopEOL;
HighlightColor color;
HighlightColor beginColor;
HighlightColor endColor;
char[] begin;
char[] end;
string name;
string rule;
HighlightRuleSet ruleSet;
char escapeCharacter;
bool ignoreCase;
bool isBeginSingleWord;
bool? isBeginStartOfLine;
bool isEndSingleWord;
internal HighlightRuleSet RuleSet {
get {
return ruleSet;
}
set {
ruleSet = value;
}
}
public bool IgnoreCase {
get {
return ignoreCase;
}
set {
ignoreCase = value;
}
}
public bool StopEOL {
get {
return stopEOL;
}
}
public bool? IsBeginStartOfLine {
get {
return isBeginStartOfLine;
}
}
public bool IsBeginSingleWord {
get {
return isBeginSingleWord;
}
}
public bool IsEndSingleWord {
get {
return isEndSingleWord;
}
}
public HighlightColor Color {
get {
return color;
}
}
public HighlightColor BeginColor {
get {
if(beginColor != null) {
return beginColor;
} else {
return color;
}
}
}
public HighlightColor EndColor {
get {
return endColor!=null ? endColor : color;
}
}
public char[] Begin {
get { return begin; }
}
public char[] End {
get { return end; }
}
public string Name {
get { return name; }
}
public string Rule {
get { return rule; }
}
///
/// Gets the escape character of the span. The escape character is a character that can be used in front
/// of the span end to make it not end the span. The escape character followed by another escape character
/// means the escape character was escaped like in @"a "" b" literals in C#.
/// The default value '\0' means no escape character is allowed.
///
public char EscapeCharacter {
get { return escapeCharacter; }
}
public Span(XmlElement span)
{
color = new HighlightColor(span);
if (span.HasAttribute("rule")) {
rule = span.GetAttribute("rule");
}
if (span.HasAttribute("escapecharacter")) {
escapeCharacter = span.GetAttribute("escapecharacter")[0];
}
name = span.GetAttribute("name");
if (span.HasAttribute("stopateol")) {
stopEOL = Boolean.Parse(span.GetAttribute("stopateol"));
}
begin = span["Begin"].InnerText.ToCharArray();
beginColor = new HighlightColor(span["Begin"], color);
if (span["Begin"].HasAttribute("singleword")) {
this.isBeginSingleWord = Boolean.Parse(span["Begin"].GetAttribute("singleword"));
}
if (span["Begin"].HasAttribute("startofline")) {
this.isBeginStartOfLine = Boolean.Parse(span["Begin"].GetAttribute("startofline"));
}
if (span["End"] != null) {
end = span["End"].InnerText.ToCharArray();
endColor = new HighlightColor(span["End"], color);
if (span["End"].HasAttribute("singleword")) {
this.isEndSingleWord = Boolean.Parse(span["End"].GetAttribute("singleword"));
}
}
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/SpanStack.cs
================================================
//
//
//
//
// $Revision: 1471 $
//
using System;
using System.Collections.Generic;
namespace ICSharpCode.TextEditor.Document
{
///
/// A stack of Span instances. Works like Stack<Span>, but can be cloned quickly
/// because it is implemented as linked list.
///
public sealed class SpanStack : ICloneable, IEnumerable
{
internal sealed class StackNode
{
public readonly StackNode Previous;
public readonly Span Data;
public StackNode(StackNode previous, Span data)
{
this.Previous = previous;
this.Data = data;
}
}
StackNode top = null;
public Span Pop()
{
Span s = top.Data;
top = top.Previous;
return s;
}
public Span Peek()
{
return top.Data;
}
public void Push(Span s)
{
top = new StackNode(top, s);
}
public bool IsEmpty {
get {
return top == null;
}
}
public SpanStack Clone()
{
SpanStack n = new SpanStack();
n.top = this.top;
return n;
}
object ICloneable.Clone()
{
return this.Clone();
}
public Enumerator GetEnumerator()
{
return new Enumerator(new StackNode(top, null));
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public struct Enumerator : IEnumerator
{
StackNode c;
internal Enumerator(StackNode node)
{
c = node;
}
public Span Current {
get {
return c.Data;
}
}
object System.Collections.IEnumerator.Current {
get {
return c.Data;
}
}
public void Dispose()
{
c = null;
}
public bool MoveNext()
{
c = c.Previous;
return c != null;
}
public void Reset()
{
throw new NotSupportedException();
}
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/SyntaxModes/FileSyntaxModeProvider.cs
================================================
//
//
//
//
// $Revision: 2533 $
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
public class FileSyntaxModeProvider : ISyntaxModeFileProvider
{
string directory;
List syntaxModes = null;
public ICollection SyntaxModes {
get {
return syntaxModes;
}
}
public FileSyntaxModeProvider(string directory)
{
this.directory = directory;
UpdateSyntaxModeList();
}
public void UpdateSyntaxModeList()
{
string syntaxModeFile = Path.Combine(directory, "SyntaxModes.xml");
if (File.Exists(syntaxModeFile)) {
Stream s = File.OpenRead(syntaxModeFile);
syntaxModes = SyntaxMode.GetSyntaxModes(s);
s.Close();
} else {
syntaxModes = ScanDirectory(directory);
}
}
public XmlTextReader GetSyntaxModeFile(SyntaxMode syntaxMode)
{
string syntaxModeFile = Path.Combine(directory, syntaxMode.FileName);
if (!File.Exists(syntaxModeFile)) {
throw new HighlightingDefinitionInvalidException("Can't load highlighting definition " + syntaxModeFile + " (file not found)!");
}
return new XmlTextReader(File.OpenRead(syntaxModeFile));
}
List ScanDirectory(string directory)
{
string[] files = Directory.GetFiles(directory);
List modes = new List();
foreach (string file in files) {
if (Path.GetExtension(file).Equals(".XSHD", StringComparison.OrdinalIgnoreCase)) {
XmlTextReader reader = new XmlTextReader(file);
while (reader.Read()) {
if (reader.NodeType == XmlNodeType.Element) {
switch (reader.Name) {
case "SyntaxDefinition":
string name = reader.GetAttribute("name");
string extensions = reader.GetAttribute("extensions");
modes.Add(new SyntaxMode(Path.GetFileName(file),
name,
extensions));
goto bailout;
default:
throw new HighlightingDefinitionInvalidException("Unknown root node in syntax highlighting file :" + reader.Name);
}
}
}
bailout:
reader.Close();
}
}
return modes;
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/SyntaxModes/ISyntaxModeFileProvider.cs
================================================
//
//
//
//
// $Revision: 1301 $
//
using System;
using System.Collections.Generic;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
public interface ISyntaxModeFileProvider
{
ICollection SyntaxModes {
get;
}
XmlTextReader GetSyntaxModeFile(SyntaxMode syntaxMode);
void UpdateSyntaxModeList();
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/SyntaxModes/ResourceSyntaxModeProvider.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
public class ResourceSyntaxModeProvider : ISyntaxModeFileProvider
{
List syntaxModes = null;
public ICollection SyntaxModes {
get {
return syntaxModes;
}
}
public ResourceSyntaxModeProvider()
{
Assembly assembly = typeof(SyntaxMode).Assembly;
Stream syntaxModeStream = assembly.GetManifestResourceStream("ICSharpCode.TextEditor.Resources.SyntaxModes.xml");
if (syntaxModeStream != null) {
syntaxModes = SyntaxMode.GetSyntaxModes(syntaxModeStream);
} else {
syntaxModes = new List();
}
}
public XmlTextReader GetSyntaxModeFile(SyntaxMode syntaxMode)
{
Assembly assembly = typeof(SyntaxMode).Assembly;
return new XmlTextReader(assembly.GetManifestResourceStream("ICSharpCode.TextEditor.Resources." + syntaxMode.FileName));
}
public void UpdateSyntaxModeList()
{
// resources don't change during runtime
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/SyntaxModes/SyntaxMode.cs
================================================
//
//
//
//
// $Revision: 2533 $
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
public class SyntaxMode
{
string fileName;
string name;
string[] extensions;
public string FileName {
get {
return fileName;
}
set {
fileName = value;
}
}
public string Name {
get {
return name;
}
set {
name = value;
}
}
public string[] Extensions {
get {
return extensions;
}
set {
extensions = value;
}
}
public SyntaxMode(string fileName, string name, string extensions)
{
this.fileName = fileName;
this.name = name;
this.extensions = extensions.Split(';', '|', ',');
}
public SyntaxMode(string fileName, string name, string[] extensions)
{
this.fileName = fileName;
this.name = name;
this.extensions = extensions;
}
public static List GetSyntaxModes(Stream xmlSyntaxModeStream)
{
XmlTextReader reader = new XmlTextReader(xmlSyntaxModeStream);
List syntaxModes = new List();
while (reader.Read()) {
switch (reader.NodeType) {
case XmlNodeType.Element:
switch (reader.Name) {
case "SyntaxModes":
string version = reader.GetAttribute("version");
if (version != "1.0") {
throw new HighlightingDefinitionInvalidException("Unknown syntax mode file defininition with version " + version);
}
break;
case "Mode":
syntaxModes.Add(new SyntaxMode(reader.GetAttribute("file"),
reader.GetAttribute("name"),
reader.GetAttribute("extensions")));
break;
default:
throw new HighlightingDefinitionInvalidException("Unknown node in syntax mode file :" + reader.Name);
}
break;
}
}
reader.Close();
return syntaxModes;
}
public override string ToString()
{
return String.Format("[SyntaxMode: FileName={0}, Name={1}, Extensions=({2})]", fileName, name, String.Join(",", extensions));
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/TextWord.cs
================================================
//
//
//
//
// $Revision: 1965 $
//
using System;
using System.Diagnostics;
using System.Drawing;
namespace ICSharpCode.TextEditor.Document
{
public enum TextWordType {
Word,
Space,
Tab
}
///
/// This class represents single words with color information, two special versions of a word are
/// spaces and tabs.
///
public class TextWord
{
HighlightColor color;
LineSegment line;
IDocument document;
int offset;
int length;
public sealed class SpaceTextWord : TextWord
{
public SpaceTextWord()
{
length = 1;
}
public SpaceTextWord(HighlightColor color)
{
length = 1;
base.SyntaxColor = color;
}
public override Font GetFont(FontContainer fontContainer)
{
return null;
}
public override TextWordType Type {
get {
return TextWordType.Space;
}
}
public override bool IsWhiteSpace {
get {
return true;
}
}
}
public sealed class TabTextWord : TextWord
{
public TabTextWord()
{
length = 1;
}
public TabTextWord(HighlightColor color)
{
length = 1;
base.SyntaxColor = color;
}
public override Font GetFont(FontContainer fontContainer)
{
return null;
}
public override TextWordType Type {
get {
return TextWordType.Tab;
}
}
public override bool IsWhiteSpace {
get {
return true;
}
}
}
static TextWord spaceWord = new SpaceTextWord();
static TextWord tabWord = new TabTextWord();
bool hasDefaultColor;
public static TextWord Space {
get {
return spaceWord;
}
}
public static TextWord Tab {
get {
return tabWord;
}
}
public int Offset {
get {
return offset;
}
}
public int Length {
get {
return length;
}
}
///
/// Splits the into two parts: the part before is assigned to
/// the reference parameter , the part after is returned.
///
public static TextWord Split(ref TextWord word, int pos)
{
#if DEBUG
if (word.Type != TextWordType.Word)
throw new ArgumentException("word.Type must be Word");
if (pos <= 0)
throw new ArgumentOutOfRangeException("pos", pos, "pos must be > 0");
if (pos >= word.Length)
throw new ArgumentOutOfRangeException("pos", pos, "pos must be < word.Length");
#endif
TextWord after = new TextWord(word.document, word.line, word.offset + pos, word.length - pos, word.color, word.hasDefaultColor);
word = new TextWord(word.document, word.line, word.offset, pos, word.color, word.hasDefaultColor);
return after;
}
public bool HasDefaultColor {
get {
return hasDefaultColor;
}
}
public virtual TextWordType Type {
get {
return TextWordType.Word;
}
}
public string Word {
get {
if (document == null) {
return String.Empty;
}
return document.GetText(line.Offset + offset, length);
}
}
public virtual Font GetFont(FontContainer fontContainer)
{
return color.GetFont(fontContainer);
}
public Color Color {
get {
if (color == null)
return Color.Black;
else
return color.Color;
}
}
public bool Bold {
get {
if (color == null)
return false;
else
return color.Bold;
}
}
public bool Italic {
get {
if (color == null)
return false;
else
return color.Italic;
}
}
public HighlightColor SyntaxColor {
get {
return color;
}
set {
Debug.Assert(value != null);
color = value;
}
}
public virtual bool IsWhiteSpace {
get {
return false;
}
}
protected TextWord()
{
}
// TAB
public TextWord(IDocument document, LineSegment line, int offset, int length, HighlightColor color, bool hasDefaultColor)
{
Debug.Assert(document != null);
Debug.Assert(line != null);
Debug.Assert(color != null);
this.document = document;
this.line = line;
this.offset = offset;
this.length = length;
this.color = color;
this.hasDefaultColor = hasDefaultColor;
}
///
/// Converts a instance to string (for debug purposes)
///
public override string ToString()
{
return "[TextWord: Word = " + Word + ", Color = " + Color + "]";
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/IDocument.cs
================================================
//
//
//
//
// $Revision: 3205 $
//
using System;
using System.Collections.Generic;
using System.Drawing;
using ICSharpCode.TextEditor.Undo;
namespace ICSharpCode.TextEditor.Document
{
///
/// This interface represents a container which holds a text sequence and
/// all necessary information about it. It is used as the base for a text editor.
///
public interface IDocument
{
ITextEditorProperties TextEditorProperties {
get;
set;
}
UndoStack UndoStack {
get;
}
///
/// If true the document can't be altered
///
bool ReadOnly {
get;
set;
}
///
/// The attached to the instance
///
IFormattingStrategy FormattingStrategy {
get;
set;
}
///
/// The attached to the instance
///
ITextBufferStrategy TextBufferStrategy {
get;
}
///
/// The attached to the instance
///
FoldingManager FoldingManager {
get;
}
///
/// The attached to the instance
///
IHighlightingStrategy HighlightingStrategy {
get;
set;
}
///
/// The attached to the instance
///
BookmarkManager BookmarkManager {
get;
}
MarkerStrategy MarkerStrategy {
get;
}
// ///
// /// The attached to the instance
// ///
// SelectionManager SelectionManager {
// get;
// }
#region ILineManager interface
///
/// A collection of all line segments
///
///
/// The collection should only be used if you're aware
/// of the 'last line ends with a delimiter problem'. Otherwise
/// the method should be used.
///
IList LineSegmentCollection {
get;
}
///
/// The total number of lines in the document.
///
int TotalNumberOfLines {
get;
}
///
/// Returns a valid line number for the given offset.
///
///
/// A offset which points to a character in the line which
/// line number is returned.
///
///
/// An int which value is the line number.
///
/// If offset points not to a valid position
int GetLineNumberForOffset(int offset);
///
/// Returns a for the given offset.
///
///
/// A offset which points to a character in the line which
/// is returned.
///
///
/// A object.
///
/// If offset points not to a valid position
LineSegment GetLineSegmentForOffset(int offset);
///
/// Returns a for the given line number.
/// This function should be used to get a line instead of getting the
/// line using the .
///
///
/// The line number which is requested.
///
///
/// A object.
///
/// If offset points not to a valid position
LineSegment GetLineSegment(int lineNumber);
///
/// Get the first logical line for a given visible line.
/// example : lineNumber == 100 foldings are in the linetracker
/// between 0..1 (2 folded, invisible lines) this method returns 102
/// the 'logical' line number
///
int GetFirstLogicalLine(int lineNumber);
///
/// Get the last logical line for a given visible line.
/// example : lineNumber == 100 foldings are in the linetracker
/// between 0..1 (2 folded, invisible lines) this method returns 102
/// the 'logical' line number
///
int GetLastLogicalLine(int lineNumber);
///
/// Get the visible line for a given logical line.
/// example : lineNumber == 100 foldings are in the linetracker
/// between 0..1 (2 folded, invisible lines) this method returns 98
/// the 'visible' line number
///
int GetVisibleLine(int lineNumber);
// ///
// /// Get the visible column for a given logical line and logical column.
// ///
// int GetVisibleColumn(int logicalLine, int logicalColumn);
///
/// Get the next visible line after lineNumber
///
int GetNextVisibleLineAbove(int lineNumber, int lineCount);
///
/// Get the next visible line below lineNumber
///
int GetNextVisibleLineBelow(int lineNumber, int lineCount);
event EventHandler LineLengthChanged;
event EventHandler LineCountChanged;
event EventHandler LineDeleted;
#endregion
#region ITextBufferStrategy interface
///
/// Get the whole text as string.
/// When setting the text using the TextContent property, the undo stack is cleared.
/// Set TextContent only for actions such as loading a file; if you want to change the current document
/// use the Replace method instead.
///
string TextContent {
get;
set;
}
///
/// The current length of the sequence of characters that can be edited.
///
int TextLength {
get;
}
///
/// Inserts a string of characters into the sequence.
///
///
/// offset where to insert the string.
///
///
/// text to be inserted.
///
void Insert(int offset, string text);
///
/// Removes some portion of the sequence.
///
///
/// offset of the remove.
///
///
/// number of characters to remove.
///
void Remove(int offset, int length);
///
/// Replace some portion of the sequence.
///
///
/// offset.
///
///
/// number of characters to replace.
///
///
/// text to be replaced with.
///
void Replace(int offset, int length, string text);
///
/// Returns a specific char of the sequence.
///
///
/// Offset of the char to get.
///
char GetCharAt(int offset);
///
/// Fetches a string of characters contained in the sequence.
///
///
/// Offset into the sequence to fetch
///
///
/// number of characters to copy.
///
string GetText(int offset, int length);
#endregion
string GetText(ISegment segment);
#region ITextModel interface
///
/// returns the logical line/column position from an offset
///
TextLocation OffsetToPosition(int offset);
///
/// returns the offset from a logical line/column position
///
int PositionToOffset(TextLocation p);
#endregion
///
/// A container where all TextAreaUpdate objects get stored
///
List UpdateQueue {
get;
}
///
/// Requests an update of the textarea
///
void RequestUpdate(TextAreaUpdate update);
///
/// Commits all updates in the queue to the textarea (the
/// textarea will be painted)
///
void CommitUpdate();
///
/// Moves, Resizes, Removes a list of segments on insert/remove/replace events.
///
void UpdateSegmentListOnDocumentChange(List list, DocumentEventArgs e) where T : ISegment;
///
/// Is fired when CommitUpdate is called
///
event EventHandler UpdateCommited;
///
///
event DocumentEventHandler DocumentAboutToBeChanged;
///
///
event DocumentEventHandler DocumentChanged;
event EventHandler TextContentChanged;
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/ISegment.cs
================================================
//
//
//
//
// $Revision: 1966 $
//
namespace ICSharpCode.TextEditor.Document
{
///
/// This interface is used to describe a span inside a text sequence
///
public interface ISegment
{
///
/// The offset where the span begins
///
int Offset {
get;
set;
}
///
/// The length of the span
///
int Length {
get;
set;
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/ITextEditorProperties.cs
================================================
//
//
//
//
// $Revision: 3205 $
//
using System;
using System.Drawing;
using System.Text;
namespace ICSharpCode.TextEditor.Document
{
public interface ITextEditorProperties
{
bool AutoInsertCurlyBracket { // is wrapped in text editor control
get;
set;
}
bool HideMouseCursor { // is wrapped in text editor control
get;
set;
}
bool IsIconBarVisible { // is wrapped in text editor control
get;
set;
}
bool AllowCaretBeyondEOL {
get;
set;
}
bool ShowMatchingBracket { // is wrapped in text editor control
get;
set;
}
bool CutCopyWholeLine {
get;
set;
}
System.Drawing.Text.TextRenderingHint TextRenderingHint { // is wrapped in text editor control
get;
set;
}
bool MouseWheelScrollDown {
get;
set;
}
bool MouseWheelTextZoom {
get;
set;
}
string LineTerminator {
get;
set;
}
LineViewerStyle LineViewerStyle { // is wrapped in text editor control
get;
set;
}
bool ShowInvalidLines { // is wrapped in text editor control
get;
set;
}
int VerticalRulerRow { // is wrapped in text editor control
get;
set;
}
bool ShowSpaces { // is wrapped in text editor control
get;
set;
}
bool ShowTabs { // is wrapped in text editor control
get;
set;
}
bool ShowEOLMarker { // is wrapped in text editor control
get;
set;
}
bool ConvertTabsToSpaces { // is wrapped in text editor control
get;
set;
}
bool ShowHorizontalRuler { // is wrapped in text editor control
get;
set;
}
bool ShowVerticalRuler { // is wrapped in text editor control
get;
set;
}
Encoding Encoding {
get;
set;
}
bool EnableFolding { // is wrapped in text editor control
get;
set;
}
bool ShowLineNumbers { // is wrapped in text editor control
get;
set;
}
///
/// The width of a tab.
///
int TabIndent { // is wrapped in text editor control
get;
set;
}
///
/// The amount of spaces a tab is converted to if ConvertTabsToSpaces is true.
///
int IndentationSize {
get;
set;
}
IndentStyle IndentStyle { // is wrapped in text editor control
get;
set;
}
DocumentSelectionMode DocumentSelectionMode {
get;
set;
}
Font Font { // is wrapped in text editor control
get;
set;
}
FontContainer FontContainer {
get;
}
BracketMatchingStyle BracketMatchingStyle { // is wrapped in text editor control
get;
set;
}
bool SupportReadOnlySegments {
get;
set;
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/LineManager/DeferredEventList.cs
================================================
//
//
//
//
// $Revision$
//
using System;
using System.Collections.Generic;
namespace ICSharpCode.TextEditor.Document
{
///
/// A list of events that are fired after the line manager has finished working.
///
struct DeferredEventList
{
internal List removedLines;
internal List textAnchor;
public void AddRemovedLine(LineSegment line)
{
if (removedLines == null)
removedLines = new List();
removedLines.Add(line);
}
public void AddDeletedAnchor(TextAnchor anchor)
{
if (textAnchor == null)
textAnchor = new List();
textAnchor.Add(anchor);
}
public void RaiseEvents()
{
// removedLines is raised by the LineManager
if (textAnchor != null) {
foreach (TextAnchor a in textAnchor) {
a.RaiseDeleted();
}
}
}
}
}
================================================
FILE: src/ICSharpCode.TextEditor/Project/Src/Document/LineManager/LineManager.cs
================================================
//
//
//
//
// $Revision: 3274 $
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ICSharpCode.TextEditor.Document
{
internal sealed class LineManager
{
LineSegmentTree lineCollection = new LineSegmentTree();
IDocument document;
IHighlightingStrategy highlightingStrategy;
public IList LineSegmentCollection {
get {
return lineCollection;
}
}
public int TotalNumberOfLines {
get {
return lineCollection.Count;
}
}
public IHighlightingStrategy HighlightingStrategy {
get {
return highlightingStrategy;
}
set {
if (highlightingStrategy != value) {
highlightingStrategy = value;
if (highlightingStrategy != null) {
highlightingStrategy.MarkTokens(document);
}
}
}
}
public LineManager(IDocument document, IHighlightingStrategy highlightingStrategy)
{
this.document = document;
this.highlightingStrategy = highlightingStrategy;
}
public int GetLineNumberForOffset(int offset)
{
return GetLineSegmentForOffset(offset).LineNumber;
}
public LineSegment GetLineSegmentForOffset(int offset)
{
return lineCollection.GetByOffset(offset);
}
public LineSegment GetLineSegment(int lineNr)
{
return lineCollection[lineNr];
}
public void Insert(int offset, string text)
{
Replace(offset, 0, text);
}
public void Remove(int offset, int length)
{
Replace(offset, length, String.Empty);
}
public void Replace(int offset, int length, string text)
{
Debug.WriteLine("Replace offset="+offset+" length="+length+" text.Length="+text.Length);
int lineStart = GetLineNumberForOffset(offset);
int oldNumberOfLines = this.TotalNumberOfLines;
DeferredEventList deferredEventList = new DeferredEventList();
RemoveInternal(ref deferredEventList, offset, length);
int numberOfLinesAfterRemoving = this.TotalNumberOfLines;
if (!string.IsNullOrEmpty(text)) {
InsertInternal(offset, text);
}
// #if DEBUG
// Console.WriteLine("New line collection:");
// Console.WriteLine(lineCollection.GetTreeAsString());
// Console.WriteLine("New text:");
// Console.WriteLine("'" + document.TextContent + "'");
// #endif
// Only fire events after RemoveInternal+InsertInternal finished completely:
// Otherwise we would expose inconsistent state to the event handlers.
RunHighlighter(lineStart, 1 + Math.Max(0, this.TotalNumberOfLines - numberOfLinesAfterRemoving));
if (deferredEventList.removedLines != null) {
foreach (LineSegment ls in deferredEventList.removedLines)
OnLineDeleted(new LineEventArgs(document, ls));
}
deferredEventList.RaiseEvents();
if (this.TotalNumberOfLines != oldNumberOfLines) {
OnLineCountChanged(new LineCountChangeEventArgs(document, lineStart, this.TotalNumberOfLines - oldNumberOfLines));
}
}
void RemoveInternal(ref DeferredEventList deferredEventList, int offset, int length)
{
Debug.Assert(length >= 0);
if (length == 0) return;
LineSegmentTree.Enumerator it = lineCollection.GetEnumeratorForOffset(offset);
LineSegment startSegment = it.Current;
int startSegmentOffset = startSegment.Offset;
if (offset + length < startSegmentOffset + startSegment.TotalLength) {
// just removing a part of this line segment
startSegment.RemovedLinePart(ref deferredEventList, offset - startSegmentOffset, length);
SetSegmentLength(startSegment, startSegment.TotalLength - length);
return;
}
// merge startSegment with another line segment because startSegment's delimiter was deleted
// possibly remove lines in between if multiple delimiters were deleted
int charactersRemovedInStartLine = startSegmentOffset + startSegment.TotalLength - offset;
Debug.Assert(charactersRemovedInStartLine > 0);
startSegment.RemovedLinePart(ref deferredEventList, offset - startSegmentOffset, charactersRemovedInStartLine);
LineSegment endSegment = lineCollection.GetByOffset(offset + length);
if (endSegment == startSegment) {
// special case: we are removing a part of the last line up to the
// end of the document
SetSegmentLength(startSegment, startSegment.TotalLength - length);
return;
}
int endSegmentOffset = endSegment.Offset;
int charactersLeftInEndLine = endSegmentOffset + endSegment.TotalLength - (offset + length);
endSegment.RemovedLinePart(ref deferredEventList, 0, endSegment.TotalLength - charactersLeftInEndLine);
startSegment.MergedWith(endSegment, offset - startSegmentOffset);
SetSegmentLength(startSegment, startSegment.TotalLength - charactersRemovedInStartLine + charactersLeftInEndLine);
startSegment.DelimiterLength = endSegment.DelimiterLength;
// remove all segments between startSegment (excl.) and endSegment (incl.)
it.MoveNext();
LineSegment segmentToRemove;
do {
segmentToRemove = it.Current;
it.MoveNext();
lineCollection.RemoveSegment(segmentToRemove);
segmentToRemove.Deleted(ref deferredEventList);
} while (segmentToRemove != endSegment);
}
void InsertInternal(int offset, string text)
{
LineSegment segment = lineCollection.GetByOffset(offset);
DelimiterSegment ds = NextDelimiter(text, 0);
if (ds == null) {
// no newline is being inserted, all text is inserted in a single line
segment.InsertedLinePart(offset - segment.Offset, text.Length);
SetSegmentLength(segment, segment.TotalLength + text.Length);
return;
}
LineSegment firstLine = segment;
firstLine.InsertedLinePart(offset - firstLine.Offset, ds.Offset);
int lastDelimiterEnd = 0;
while (ds != null) {
// split line segment at line delimiter
int lineBreakOffset = offset + ds.Offset + ds.Length;
int segmentOffset = segment.Offset;
int lengthAfterInsertionPos = segmentOffset + segment.TotalLength - (offset + lastDelimiterEnd);
lineCollection.SetSegmentLength(segment, lineBreakOffset - segmentOffset);
LineSegment newSegment = lineCollection.InsertSegmentAfter(segment, lengthAfterInsertionPos);
segment.DelimiterLength = ds.Length;
segment = newSegment;
lastDelimiterEnd = ds.Offset + ds.Length;
ds = NextDelimiter(text, lastDelimiterEnd);
}
firstLine.SplitTo(segment);
// insert rest after last delimiter
if (lastDelimiterEnd != text.Length) {
segment.InsertedLinePart(0, text.Length - lastDelimiterEnd);
SetSegmentLength(segment, segment.TotalLength + text.Length - lastDelimiterEnd);
}
}
void SetSegmentLength(LineSegment segment, int newTotalLength)
{
int delta = newTotalLength - segment.TotalLength;
if (delta != 0) {
lineCollection.SetSegmentLength(segment, newTotalLength);
OnLineLengthChanged(new LineLengthChangeEventArgs(document, segment, delta));
}
}
void RunHighlighter(int firstLine, int lineCount)
{
if (highlightingStrategy != null) {
List markLines = new List();
LineSegmentTree.Enumerator it = lineCollection.GetEnumeratorForIndex(firstLine);
for (int i = 0; i < lineCount && it.IsValid; i++) {
markLines.Add(it.Current);
it.MoveNext();
}
highlightingStrategy.MarkTokens(document, markLines);
}
}
public void SetContent(string text)
{
lineCollection.Clear();
if (text != null) {
Replace(0, 0, text);
}
}
public int GetVisibleLine(int logicalLineNumber)
{
if (!document.TextEditorProperties.EnableFolding) {
return logicalLineNumber;
}
int visibleLine = 0;
int foldEnd = 0;
List foldings = document.FoldingManager.GetTopLevelFoldedFoldings();
foreach (FoldMarker fm in foldings) {
if (fm.StartLine >= logicalLineNumber) {
break;
}
if (fm.StartLine >= foldEnd) {
visibleLine += fm.StartLine - foldEnd;
if (fm.EndLine > logicalLineNumber) {
return visibleLine;
}
foldEnd = fm.EndLine;
}
}
// Debug.Assert(logicalLineNumber >= foldEnd);
visibleLine += logicalLineNumber - foldEnd;
return visibleLine;
}
public int GetFirstLogicalLine(int visibleLineNumber)
{
if (!document.TextEditorProperties.EnableFolding) {
return visibleLineNumber;
}
int v = 0;
int foldEnd = 0;
List