├── .gitattributes
├── .github
├── FUNDING.yml
├── assets
│ └── star_us.gif
└── workflows
│ └── dotnet.yml
├── .gitignore
├── .vscode
├── launch.json
└── tasks.json
├── CodeAnalyzers.targets
├── ConfigParser.sln
├── Directory.Build.props
├── Directory.Build.targets
├── LICENSE
├── README.md
├── appveyor.yml
├── global.json
├── src
├── ConfigParser.NullSection.cs
├── ConfigParser.cs
├── ConfigParser.csproj
├── ConfigParser.csproj.DotSettings
├── ConfigParserException.cs
├── ConfigParserSettings.cs
├── Entries
│ ├── ConfigComment.cs
│ ├── ConfigKeyValue.cs
│ ├── ConfigLine.cs
│ ├── ConfigSection.cs
│ ├── ConfigSectionBase.cs
│ ├── IConfigKeyValue.cs
│ └── IConfigLine.cs
└── Helpers
│ ├── FileInfoExtensions.cs
│ ├── Logging.cs
│ └── YesNoConverter.cs
└── tests
├── ConfigParser.Tests.csproj
├── ConfigParser.Tests.csproj.DotSettings
├── ConfigParserTests.cs
├── IntegrationTests.cs
├── JsonHelpers
├── ConfigParserSettingsResolver.cs
├── CultureConverter.cs
├── EncodingConverter.cs
└── EnumConverter.cs
└── Resources
├── Encoding
├── ANSI Cyrillic.txt
├── ANSI Latin1.txt
├── UTF16-BE.txt
├── UTF16-BE.txt.json
├── UTF16-LE.txt
├── UTF16-LE.txt.json
├── UTF32-BE.txt
├── UTF32-BE.txt.json
├── UTF7.txt
├── UTF7.txt.json
├── UTF8-Without-BOM.txt
├── UTF8-Without-BOM.txt.json
├── UTF8.txt
└── UTF8.txt.json
├── RealWorld
├── CONFIG.SYS
├── CONFIG.SYS.json
├── FALLOUT.INI
├── FALLOUT.INI.json
├── Gothic.INI
├── ROTK.ini
├── main.cf.default
├── main.cf.default.json
├── mysqld.cnf
├── mysqld.cnf.json
├── openssl.cnf
├── openssl.cnf.json
├── redis.conf
├── redis.conf.json
├── skinr.help.ini
├── wakatime.cfg
└── wakatime.cfg.json
├── Structure
├── from-scratch.conf
├── indented.ini
├── interpolation.conf
├── multi-line-delimited.ini
├── multi-line.ini
├── only-comments.ini
└── simple-keys.ini
└── Values
├── array.cnf
├── boolean.ini
└── double.conf
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: salaros # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: salaros # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: https://www.paypal.me/salarosUSA # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/assets/star_us.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salaros/config-parser/3ed0da9ae156228154d816f12c85c8f7684c7c65/.github/assets/star_us.gif
--------------------------------------------------------------------------------
/.github/workflows/dotnet.yml:
--------------------------------------------------------------------------------
1 | name: Build Config Parser
2 |
3 | on:
4 | push:
5 | branches: [ "master" ]
6 |
7 | pull_request:
8 | branches: [ "master" ]
9 |
10 | jobs:
11 | build:
12 | runs-on: windows-latest
13 |
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v3
17 | with:
18 | fetch-depth: 0
19 |
20 | # Install the .NET Core workload
21 | - name: Install .NET Core
22 | uses: actions/setup-dotnet@v2
23 | with:
24 | dotnet-version: 6.0.x
25 |
26 | - name: Setup NuGet.exe
27 | uses: NuGet/setup-nuget@v1
28 | with:
29 | nuget-api-key: ${{secrets.NUGET_API_KEY}}
30 |
31 | # Execute all unit tests in the solution
32 | - name: Execute unit tests
33 | run: |
34 | dotnet restore
35 | dotnet build --no-restore
36 |
37 | # Execute all unit tests in the solution
38 | - name: Execute unit tests
39 | run: dotnet test tests --no-build --no-restore
40 |
41 |
42 | - name: Use GitVersion to generate SemVer version
43 | if: startsWith(github.ref, 'refs/tags')
44 | run: |
45 | dotnet tool update gitversion.tool --tool-path .github/tools
46 | echo ::set-env name=TAG_VERSION::$(.github/tools/dotnet-gitversion /output json /showvariable SemVer)
47 |
48 | - name: Set package version
49 | if: startsWith(github.ref, 'refs/tags')
50 | uses: KageKirin/set-csproj-version@v1
51 | with:
52 | version: ${{ env.TAG_NAME }}
53 |
54 | - name: NuGet push
55 | if: startsWith(github.ref, 'refs/tags')
56 | run: nuget push **\*.nupkg
57 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # Exclude NuGet packages
5 | packages
6 |
7 | # User-specific files
8 | *.suo
9 | *.user
10 | *.sln.docstates
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | x64/
18 | build/
19 | bld/
20 | [Bb]in/
21 | [Oo]bj/
22 |
23 | # Roslyn cache directories
24 | *.ide/
25 |
26 | # MSTest test Results
27 | [Tt]est[Rr]esult*/
28 | [Bb]uild[Ll]og.*
29 |
30 | #NUNIT
31 | *.VisualState.xml
32 | TestResult.xml
33 |
34 | # Build Results of an ATL Project
35 | [Dd]ebugPS/
36 | [Rr]eleasePS/
37 | dlldata.c
38 |
39 | *_i.c
40 | *_p.c
41 | *_i.h
42 | *.ilk
43 | *.meta
44 | *.obj
45 | *.pch
46 | *.pdb
47 | *.pgc
48 | *.pgd
49 | *.rsp
50 | *.sbr
51 | *.tlb
52 | *.tli
53 | *.tlh
54 | *.tmp
55 | *.tmp_proj
56 | *.log
57 | *.vspscc
58 | *.vssscc
59 | .builds
60 | *.pidb
61 | *.svclog
62 | *.scc
63 |
64 | # Chutzpah Test files
65 | _Chutzpah*
66 |
67 | # Visual C++ cache files
68 | ipch/
69 | *.aps
70 | *.ncb
71 | *.opensdf
72 | *.sdf
73 | *.cachefile
74 |
75 | # Visual Studio profiler
76 | *.psess
77 | *.vsp
78 | *.vspx
79 |
80 | # TFS 2012 Local Workspace
81 | $tf/
82 |
83 | # Guidance Automation Toolkit
84 | *.gpState
85 |
86 | # ReSharper is a .NET coding add-in
87 | _ReSharper*/
88 | *.[Rr]e[Ss]harper
89 | *.DotSettings.user
90 |
91 | # JustCode is a .NET coding addin-in
92 | .JustCode
93 |
94 | # TeamCity is a build add-in
95 | _TeamCity*
96 |
97 | # DotCover is a Code Coverage Tool
98 | *.dotCover
99 |
100 | # NCrunch
101 | _NCrunch_*
102 | .*crunch*.local.xml
103 |
104 | # MightyMoose
105 | *.mm.*
106 | AutoTest.Net/
107 |
108 | # Web workbench (sass)
109 | .sass-cache/
110 |
111 | # Installshield output folder
112 | [Ee]xpress/
113 |
114 | # DocProject is a documentation generator add-in
115 | DocProject/buildhelp/
116 | DocProject/Help/*.HxT
117 | DocProject/Help/*.HxC
118 | DocProject/Help/*.hhc
119 | DocProject/Help/*.hhk
120 | DocProject/Help/*.hhp
121 | DocProject/Help/Html2
122 | DocProject/Help/html
123 |
124 | # Click-Once directory
125 | publish/
126 |
127 | # Publish Web Output
128 | *.[Pp]ublish.xml
129 | *.azurePubxml
130 | ## TODO: Comment the next line if you want to checkin your
131 | ## web deploy settings but do note that will include unencrypted
132 | ## passwords
133 | #*.pubxml
134 |
135 | # NuGet Packages Directory
136 | packages/*
137 | ## TODO: If the tool you use requires repositories.config
138 | ## uncomment the next line
139 | #!packages/repositories.config
140 |
141 | # Enable "build/" folder in the NuGet Packages folder since
142 | # NuGet packages use it for MSBuild targets.
143 | # This line needs to be after the ignore of the build folder
144 | # (and the packages folder if the line above has been uncommented)
145 | !packages/build/
146 |
147 | # Windows Azure Build Output
148 | csx/
149 | *.build.csdef
150 |
151 | # Windows Store app package directory
152 | AppPackages/
153 |
154 | # Others
155 | sql/
156 | *.Cache
157 | ClientBin/
158 | [Ss]tyle[Cc]op.*
159 | ~$*
160 | *~
161 | *.dbmdl
162 | *.dbproj.schemaview
163 | *.pfx
164 | *.publishsettings
165 | node_modules/
166 |
167 | # RIA/Silverlight projects
168 | Generated_Code/
169 |
170 | # Backup & report files from converting an old project file
171 | # to a newer Visual Studio version. Backup files are not needed,
172 | # because we have git ;-)
173 | _UpgradeReport_Files/
174 | Backup*/
175 | UpgradeLog*.XML
176 | UpgradeLog*.htm
177 |
178 | # SQL Server files
179 | *.mdf
180 | *.ldf
181 |
182 | # Business Intelligence projects
183 | *.rdl.data
184 | *.bim.layout
185 | *.bim_*.settings
186 |
187 | # Microsoft Fakes
188 | FakesAssemblies/
189 |
190 | # LightSwitch generated files
191 | GeneratedArtifacts/
192 | _Pvt_Extensions/
193 | ModelManifest.xml
194 |
195 | # Visual Studio settings folder
196 | .vs
197 |
198 | # Exclude dotnet/NuGet tools
199 | tools/
200 |
201 | # Exclude coverage results
202 | tests/coverage\.xml
203 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to find out which attributes exist for C# debugging
3 | // Use hover for the description of the existing attributes
4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": ".NET Core Launch (console)",
9 | "type": "coreclr",
10 | "request": "launch",
11 | "preLaunchTask": "build",
12 | // If you have changed target frameworks, make sure to update the program path.
13 | "program": "${workspaceFolder}/tests/bin/Debug/netcoreapp2.1/ConfigParser.Tests.dll",
14 | "args": [],
15 | "cwd": "${workspaceFolder}/tests",
16 | // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
17 | "console": "internalConsole",
18 | "stopAtEntry": false,
19 | "internalConsoleOptions": "openOnSessionStart"
20 | },
21 | {
22 | "name": ".NET Core Attach",
23 | "type": "coreclr",
24 | "request": "attach",
25 | "processId": "${command:pickProcess}"
26 | }
27 | ,
28 | {
29 | "name": ".NET Core Launch (console)",
30 | "type": "coreclr",
31 | "request": "launch",
32 | "preLaunchTask": "build",
33 | "program": "${workspaceFolder}/tests/bin/Debug/netcoreapp2.1/ConfigParser.Tests.dll",
34 | "args": [],
35 | "cwd": "${workspaceFolder}/tests",
36 | "console": "internalConsole",
37 | "stopAtEntry": false,
38 | "internalConsoleOptions": "openOnSessionStart"
39 | },
40 | {
41 | "name": ".NET Core Attach",
42 | "type": "coreclr",
43 | "request": "attach",
44 | "processId": "${command:pickProcess}"
45 | }
46 | ]
47 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "build",
6 | "command": "dotnet",
7 | "type": "process",
8 | "args": [
9 | "build",
10 | "${workspaceFolder}/tests/ConfigParser.Tests.csproj"
11 | ],
12 | "problemMatcher": "$msCompile"
13 | },
14 | {
15 | "label": "build",
16 | "command": "dotnet",
17 | "type": "process",
18 | "args": [
19 | "build",
20 | "${workspaceFolder}/tests/ConfigParser.Tests.csproj"
21 | ],
22 | "problemMatcher": "$msCompile"
23 | }
24 | ]
25 | }
--------------------------------------------------------------------------------
/CodeAnalyzers.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 | $(MSBuildThisFileDirectory)
13 |
14 |
15 |
16 |
17 |
24 | $(NoWarn),1573,1591,1712
25 |
26 |
27 |
28 |
29 | false
30 | true
31 | true
32 | $(SolutionDir)\stylecop.ruleset
33 |
34 |
35 |
36 |
37 |
38 |
39 | all
40 | runtime; build; native; contentfiles; analyzers; buildtransitive
41 |
42 |
43 |
44 |
45 |
46 | all
47 | runtime; build; native; contentfiles; analyzers; buildtransitive
48 |
49 |
50 |
51 |
52 | all
53 | runtime; build; native; contentfiles; analyzers; buildtransitive
54 |
55 |
56 |
57 |
58 | all
59 | runtime; build; native; contentfiles; analyzers
60 |
61 |
62 |
63 |
67 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/ConfigParser.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30611.23
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfigParser", "src\ConfigParser.csproj", "{B835EC8E-1BD4-4B41-A01B-E5C80B4F51C0}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{610826DA-5E33-40B5-AF2C-27DA4A73FDA1}"
9 | ProjectSection(SolutionItems) = preProject
10 | .gitattributes = .gitattributes
11 | .gitignore = .gitignore
12 | appveyor.yml = appveyor.yml
13 | CodeAnalyzers.targets = CodeAnalyzers.targets
14 | Directory.Build.props = Directory.Build.props
15 | Directory.Build.targets = Directory.Build.targets
16 | global.json = global.json
17 | LICENSE = LICENSE
18 | README.md = README.md
19 | EndProjectSection
20 | EndProject
21 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfigParser.Tests", "tests\ConfigParser.Tests.csproj", "{1949CF4D-6ACB-49D1-BBEC-D5E4CCE96946}"
22 | EndProject
23 | Global
24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
25 | Debug|Any CPU = Debug|Any CPU
26 | Debug|x86 = Debug|x86
27 | Release|Any CPU = Release|Any CPU
28 | Release|x86 = Release|x86
29 | EndGlobalSection
30 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
31 | {B835EC8E-1BD4-4B41-A01B-E5C80B4F51C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {B835EC8E-1BD4-4B41-A01B-E5C80B4F51C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {B835EC8E-1BD4-4B41-A01B-E5C80B4F51C0}.Debug|x86.ActiveCfg = Debug|Any CPU
34 | {B835EC8E-1BD4-4B41-A01B-E5C80B4F51C0}.Debug|x86.Build.0 = Debug|Any CPU
35 | {B835EC8E-1BD4-4B41-A01B-E5C80B4F51C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {B835EC8E-1BD4-4B41-A01B-E5C80B4F51C0}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {B835EC8E-1BD4-4B41-A01B-E5C80B4F51C0}.Release|x86.ActiveCfg = Release|Any CPU
38 | {B835EC8E-1BD4-4B41-A01B-E5C80B4F51C0}.Release|x86.Build.0 = Release|Any CPU
39 | {1949CF4D-6ACB-49D1-BBEC-D5E4CCE96946}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
40 | {1949CF4D-6ACB-49D1-BBEC-D5E4CCE96946}.Debug|Any CPU.Build.0 = Debug|Any CPU
41 | {1949CF4D-6ACB-49D1-BBEC-D5E4CCE96946}.Debug|x86.ActiveCfg = Debug|Any CPU
42 | {1949CF4D-6ACB-49D1-BBEC-D5E4CCE96946}.Debug|x86.Build.0 = Debug|Any CPU
43 | {1949CF4D-6ACB-49D1-BBEC-D5E4CCE96946}.Release|Any CPU.ActiveCfg = Release|Any CPU
44 | {1949CF4D-6ACB-49D1-BBEC-D5E4CCE96946}.Release|Any CPU.Build.0 = Release|Any CPU
45 | {1949CF4D-6ACB-49D1-BBEC-D5E4CCE96946}.Release|x86.ActiveCfg = Release|Any CPU
46 | {1949CF4D-6ACB-49D1-BBEC-D5E4CCE96946}.Release|x86.Build.0 = Release|Any CPU
47 | EndGlobalSection
48 | GlobalSection(SolutionProperties) = preSolution
49 | HideSolutionNode = FALSE
50 | EndGlobalSection
51 | GlobalSection(ExtensibilityGlobals) = postSolution
52 | SolutionGuid = {C925688F-B1AA-4F13-A48C-D5538AA5B08E}
53 | EndGlobalSection
54 | EndGlobal
55 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 8.0
5 | true
6 |
7 |
8 |
9 |
10 | Debug;Release
11 | true
12 | true
13 | $(MSBuildThisFileDirectory)
14 | $(SolutionDir)\bin\$(Configuration)\
15 |
16 |
17 |
18 |
19 | $(MSBuildProjectName.Contains('.Test'))
20 |
21 |
22 |
23 | bin\$(Configuration)\
24 |
25 | true
26 |
27 |
28 |
29 |
30 | true
31 | opencover
32 | $(SolutionDir)/tests/coverage/
33 |
34 |
35 |
36 |
37 | Debug
38 | AnyCPU
39 |
40 |
41 | $(DefineConstants);DEBUG
42 | true
43 | portable
44 |
45 |
46 | full
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 | $(MSBuildThisFileDirectory)
13 |
14 |
15 |
16 |
17 |
24 | $(NoWarn),1573,1591,1712
25 |
26 |
27 |
28 |
29 | false
30 | true
31 | true
32 | $(SolutionDir)\stylecop.ruleset
33 |
34 |
35 |
36 |
37 |
38 |
39 | all
40 | runtime; build; native; contentfiles; analyzers; buildtransitive
41 |
42 |
43 |
44 |
45 |
46 | all
47 | runtime; build; native; contentfiles; analyzers; buildtransitive
48 |
49 |
50 |
51 |
52 | all
53 | runtime; build; native; contentfiles; analyzers; buildtransitive
54 |
55 |
56 |
57 |
58 | all
59 | runtime; build; native; contentfiles; analyzers
60 |
61 |
62 |
63 |
67 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2015 Zhmayev Yaroslav aka Salaros
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ConfigParser
2 | [](https://ci.appveyor.com/project/salaros/configparser)
3 | [](https://ci.appveyor.com/project/salaros/configparser/build/tests)
4 | [](https://coveralls.io/github/salaros/config-parser?branch=master)
5 | =============
6 |
7 | 
8 | [](https://en.wikipedia.org/wiki/Cross-platform)
9 | [](https://social.msdn.microsoft.com/Forums/vstudio/en-US/7035edc6-97fc-49ee-8eee-2fa4d040a63b/)
10 | [](https://social.msdn.microsoft.com/Forums/vstudio/en-US/7035edc6-97fc-49ee-8eee-2fa4d040a63b/)
11 |
12 | [](https://github.com/salaros/configparser/blob/master/LICENSE)
13 | [](https://www.nuget.org/packages/Salaros.ConfigParser)
14 | [](https://www.nuget.org/packages/Salaros.ConfigParser)
15 | [](https://www.nuget.org/packages/Salaros.ConfigParser)
16 |
17 | [](https://www.patreon.com/salaros/)
18 | [](https://paypal.me/salarosIT)
19 | [](https://liberapay.com/salaros/)
20 |
21 | **ConfigParser** - is a slim, cross-platform, fully managed C# library for reading and writing .ini, .conf, .cfg etc configuration files.
22 |
23 | You could use it in your [Unity 3D](https://unity3d.com/), [Xamarin](http://xamarin.com) (iOS & Android), .NET Framework applications (even with old 4.0/4.5), .NET Core CLI and ASP.NET Core applications, [Mono](https://www.mono-project.com/) etc
24 |
25 | Features
26 | ========
27 |
28 | ## Customization
29 |
30 | - [x] customizable encoding (most encodings can be auto-detected)
31 | - [x] customizable culture
32 | - [x] customizable number styles (e.g. currencies, exponential notation etc)
33 | - [x] customizable line endings (usually auto-detected)
34 | - [x] customizable true and false (e.g. "verum" / "falsum" )
35 | - [x] customizable comment characters
36 | - [x] customizable key/value separator (defaults to '=')
37 |
38 | ## Read and preserved
39 |
40 | - [x] file header comments
41 | - [x] config files with no sections (like in this [SectionName]) or even mixed: first section has no header, just keys
42 | - [x] comments in general
43 | - [x] section comments
44 | - [x] empty lines
45 | - [x] indented sections
46 | - [x] indented keys
47 | - [x] indented values
48 |
49 | ## Values
50 |
51 | - [x] default values
52 | - [x] multi-line values (both quoted and not)
53 | - [x] quoted values
54 | - [x] null values (value-less keys)
55 | - [x] array values
56 | - [x] fancy float / double
57 | - [x] byte-encoded values
58 | - [x] smart boolean values (0/1, on/off, enabled/disabled work of the box)
59 |
60 | and more...
61 |
62 | ## 🟊🟊🟊 Support this project 🟊🟊🟊
63 |
64 | You can support us in a small way, please consider starring and sharing this repo! It helps us getting known and grow the community.
65 |
66 | 
67 |
68 | Installation
69 | ============
70 |
71 | **Config Parser** can be installed via [NuGet](https://www.nuget.org/packages/Salaros.ConfigParser)
72 | by using Package Manager in your IDE, `dotnet` binary or Package Console
73 |
74 | ```bash
75 | # Add the Salaros.ConfigParser package to a project named []
76 | dotnet add [] package Salaros.ConfigParser
77 | ```
78 |
79 | or Visual Studio's Package Console
80 |
81 | ```powershell
82 | # Add the Salaros.ConfigParser package to the default project
83 | Install-Package Salaros.ConfigParser
84 |
85 | # Add the Salaros.ConfigParser package to a project named []
86 | Install-Package Salaros.ConfigParser -ProjectName []
87 | ```
88 |
89 | Usage
90 | =====
91 |
92 | ```csharp
93 | // Initialize config file instance from file
94 | var configFileFromPath = new ConfigParser(@"path\to\configfile.cnf");
95 |
96 | // Parse text
97 | var configFileFromString = new ConfigParser(@"
98 | [Strings]
99 | canBeIndented = value
100 | andQuoted = ""quotes will be stripped""
101 |
102 | [Numbers]
103 | withD = 0.6D
104 | dollars = $2,999
105 |
106 | [boolean]
107 | numericTrue = 1
108 | textFalse = true
109 | yesWorks = yes
110 | upperCaseWorks = on
111 | worksAsWell = Enabled
112 |
113 | [Advanced]
114 | arrayWorkToo =
115 | arrayElement1
116 | arrayElement2
117 | valueLessKey",
118 | new ConfigParserSettings
119 | {
120 | MultiLineValues = MultiLineValues.Simple | MultiLineValues.AllowValuelessKeys | MultiLineValues.QuoteDelimitedValues,
121 | Culture = new CultureInfo("en-US")
122 | }
123 | );
124 |
125 | configFileFromString.GetValue("Strings", "canBeIndented"); // value
126 | configFileFromString["Strings"]["canBeIndented"]; // returns 'value' too
127 | configFileFromString.GetValue("Strings", "andQuoted"); // quotes will be stripped
128 |
129 | configFileFromString.GetValue("Numbers", "withD", 0D); // 0,6
130 | configFileFromString.GetValue("Numbers", "dollars", 0D, // 2999
131 | NumberStyles.AllowCurrencySymbol);
132 | configFileFromString.GetValue("Numbers", "dollars"); // $2,999
133 |
134 | configFileFromString.GetValue("boolean", "numericTrue", false); // True
135 | configFileFromString.GetValue("boolean", "textFalse", false); // True
136 | configFileFromString.GetValue("boolean", "yesWorks", false); // True
137 | configFileFromString.GetValue("boolean", "upperCaseWorks", false); // True
138 | configFileFromString.GetValue("boolean", "worksAsWell", false); // True
139 |
140 | configFileFromString.GetArrayValue("Advanced", "arraysWorkToo"); // ["arrayElement1","arrayElement2"]
141 | configFileFromString.GetValue("Advanced", "valueLessKey"); //
142 | ```
143 |
144 | How to build
145 | ============
146 |
147 | You need Git and [.NET Core SDK](https://www.microsoft.com/net/download/)
148 |
149 | ```bash
150 | git clone https://github.com/salaros/ConfigParser
151 | cd ConfigParser
152 | dotnet build
153 | ```
154 |
155 | How to test
156 | ===========
157 |
158 | **ConfigParser** uses [xUnit.net](https://xunit.github.io/), so you can run unit tests by simply using the following command:
159 |
160 | ```bash
161 | dotnet test tests
162 | ```
163 |
164 | License
165 | =======
166 |
167 | **ConfigParser** is distributed under the [MIT license](LICENSE), which grants you
168 |
169 | - [x] Private use
170 | - [x] Commercial use
171 | - [x] Modification
172 | - [x] Distribution
173 |
174 | However you have to include the content of [license](LICENSE) file in your source code (if you distribute your Software in text form), otherwise include it in your own LICENSE file or to some sort of **About -> Open-source libraries** section if you distribute your Software as a compiled library / binary.
175 | Here is why (part of [MIT license](LICENSE)):
176 |
177 | ```
178 | The above copyright notice and this permission notice
179 | shall be included in all copies or substantial portions of the Software.
180 | ```
181 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | # Operating system (build VM template)
2 | os: Windows Server 2019
3 |
4 | # If the build configuration does not specify build worker image
5 | # then Visual Studio 2015 image is used.
6 | image: Visual Studio 2019
7 |
8 | # Restrict to Git branches below
9 | branches:
10 | only:
11 | - master
12 |
13 | # Build Configuration, i.e. Debug, Release, etc.
14 | configuration: Debug
15 |
16 | # Scripts that run after cloning repository
17 | install:
18 | - cmd: dotnet restore
19 |
20 | environment:
21 | VERSION_SIMPLE: '{version}'
22 | VERSION_INFORMATIONAL: '{version}'
23 | VERSION_UNSTABLE_SUFFIX: 'preview'
24 | COVERALLS_REPO_TOKEN:
25 | secure: SwUOMUwmhBrcTwFa+ySSMLZ9c6G9nD/J2TJzYt/ZPiR9v2zGgKrN9UCswn1IIYKx
26 | APPVEYOR_TOKEN:
27 | secure: LtoVAPATN9iTCl1zkCvEktqP92QSEEngyS3vqG3GphE=
28 |
29 | init:
30 | - ps: |
31 | $env:VERSION_SIMPLE = $env:APPVEYOR_BUILD_VERSION.TrimStart("v")
32 | $env:VERSION_INFORMATIONAL = "$env:VERSION_SIMPLE"
33 | $env:GITHUB_REPO_API = "https://api.github.com/repos/$env:APPVEYOR_REPO_NAME/tags"
34 |
35 | if ($env:APPVEYOR_REPO_TAG -eq "true" -and $env:APPVEYOR_REPO_TAG_NAME) {
36 | ### CHECK IF A IT'S A TAGGED BUILD
37 | $env:APPVEYOR_REPO_TAG_NAME = $env:APPVEYOR_REPO_TAG_NAME.TrimStart("v")
38 | Write-Host "Building a tagged Git commit: $git_current_tag";
39 | if ($env:APPVEYOR_REPO_TAG_NAME -match '^([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)$') {
40 | $tag_ver = [version]$env:APPVEYOR_REPO_TAG_NAME
41 | $env:VERSION_INFORMATIONAL = "{0}.{1}.{2}" -f $tag_ver.Major, $tag_ver.Minor, $tag_ver.Build
42 | $env:VERSION_SIMPLE = "$env:VERSION_INFORMATIONAL.$env:APPVEYOR_BUILD_NUMBER"
43 | }
44 | } elseif ($env:VERSION_INFORMATIONAL -match '^([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)$') {
45 | $current_ver = [version]$env:VERSION_INFORMATIONAL
46 | $env:VERSION_INFORMATIONAL = "{0}.{1}.{2}" -f $current_ver.Major, $current_ver.Minor, $current_ver.Build
47 | $env:VERSION_INFORMATIONAL = "{0}-{1}{2}" -f $env:VERSION_INFORMATIONAL, $env:VERSION_UNSTABLE_SUFFIX, $env:APPVEYOR_BUILD_NUMBER
48 | }
49 |
50 | ### MAKE CALCULATED INFORMATIONAL VERSION THE ACTUAL BUILD VERSION
51 | Update-AppveyorBuild -Version $env:VERSION_INFORMATIONAL
52 | Write-Host "Using build version: $env:VERSION_SIMPLE"
53 | Write-Host "Using (informational) build version: $env:VERSION_INFORMATIONAL"
54 |
55 | dotnet_csproj:
56 | patch: true
57 | file: '**\*.csproj'
58 | assembly_version: $(VERSION_SIMPLE)
59 | file_version: $(VERSION_SIMPLE)
60 | version: $(VERSION_INFORMATIONAL)
61 | package_version: $(VERSION_INFORMATIONAL)
62 | informational_version: $(VERSION_INFORMATIONAL)
63 |
64 | # Run scripts below before
65 | before_build:
66 | - cmd: where dotnet
67 | - cmd: dotnet clean
68 |
69 | # Run scripts below before
70 | build_script:
71 | - cmd: dotnet build
72 |
73 | # NuGet files qualified as artifacts
74 | artifacts:
75 | - path: 'bin\**\*.nupkg' # find the NuGet files
76 | name: NuGet_Files
77 |
78 | # Deploy to GitHub releases
79 | deploy:
80 | -
81 | provider: GitHub
82 | auth_token:
83 | secure: 2+d0KgCbWQpUR8TZfzvUEzbi4NQP6F/Tt0PUwLn6jXZCyO8FnrFVFJPsFa0QBQFl
84 | artifact: NuGet_Files
85 | draft: false
86 | force_update: true
87 | prerelease: false
88 | release: "$(APPVEYOR_PROJECT_NAME) v$(APPVEYOR_REPO_TAG_NAME)"
89 | tag: $(APPVEYOR_REPO_TAG_NAME)
90 | on:
91 | appveyor_repo_tag: true
92 |
93 | -
94 | provider: NuGet
95 | api_key:
96 | secure: fLRrY6iKFQhPFD5fHraib6Ot+0x3eKiVWoBCiKT5zPRCqxWxLAycIO8lJWg3o43r
97 | artifact: NuGet_Files
98 | server: # remove to push to NuGet.org
99 | skip_symbols: false
100 | symbol_server: # remove to push symbols to SymbolSource.org
101 |
102 | -
103 | provider: NuGet
104 | server: https://ci.appveyor.com/nuget/salaros/api/v2/package
105 | symbol_server: https://ci.appveyor.com/nuget/salaros/api/v2/package
106 | api_key:
107 | secure: 3zmnmVBweTgdk4SBM/rWHdC9JOM9s0pxm1bw1d+WHDo=
108 | artifact: NuGet_Files
109 |
110 | after_deploy:
111 | - ps: |
112 | if ($env:APPVEYOR_REPO_TAG -eq "true" -and $env:APPVEYOR_REPO_TAG_NAME) {
113 | $apiUrl = 'https://ci.appveyor.com/api'
114 | $headers = @{
115 | "Authorization" = "Bearer $env:APPVEYOR_TOKEN"
116 | "Content-type" = "application/json"
117 | }
118 | Invoke-RestMethod -Method Put "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/settings/build-number" -Body '{"nextBuildNumber": 1 }' -Headers $headers
119 | $env:APPVEYOR_REPO_TAG_NAME = $env:APPVEYOR_REPO_TAG_NAME.TrimStart("v")
120 | if ($env:APPVEYOR_REPO_TAG_NAME -match '^([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)$') {
121 | $tag_ver = [version]$env:APPVEYOR_REPO_TAG_NAME
122 | $ver_format = "version: {0}.{1}.{2}.{3}" -f $tag_ver.Major, $tag_ver.Minor, ($tag_ver.Build + 1), '{build}'
123 | $headers."Content-type" = "text/plain";
124 | Invoke-RestMethod -Method Put "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/settings/yaml" -Body $ver_format -Headers $headers
125 | }
126 | }
127 |
128 | # Start builds on tags only (GitHub and BitBucket)
129 | skip_non_tags: false
130 |
131 | # Tests shall stay off for now
132 | test_script:
133 | - cmd: dotnet test .\tests
134 |
135 | # Test coverage: OpenCover + Coveralls
136 | after_test:
137 | - ps: |
138 | # Install NuGet packages and tools
139 | nuget install OpenCover -Version 4.6.519 -OutputDirectory packages
140 | dotnet tool install coveralls.net --tool-path tools
141 |
142 | # Set variables
143 | .\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -target:dotnet.exe -targetargs:"test tests" -register:user -filter:"+[*]* -[xunit*]* -[*Tests]* -[*]*.Logging.*" -excludedirs:"src\obj;src\Helpers;Helpers" -output:"tests\coverage.xml" -oldStyle
144 | .\tools\csmacnz.Coveralls.exe --opencover -i .\tests\coverage.xml --repoToken $env:COVERALLS_REPO_TOKEN --commitId $env:APPVEYOR_REPO_COMMIT --commitBranch $env:APPVEYOR_REPO_BRANCH --commitAuthor $env:APPVEYOR_REPO_COMMIT_AUTHOR --commitEmail $env:APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL --commitMessage "$env:APPVEYOR_REPO_COMMIT_MESSAGE" --jobId $env:APPVEYOR_JOB_ID
145 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "projects": [
3 | "src",
4 | "tests"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/src/ConfigParser.NullSection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace Salaros.Configuration
5 | {
6 | public partial class ConfigParser
7 | {
8 | public class NullConfigSection
9 | {
10 | private ConfigParser parent;
11 |
12 | public NullConfigSection(ConfigParser parent)
13 | {
14 | this.parent = parent;
15 | }
16 |
17 | public T GetValue(string keyName, T defaultValue = default(T))
18 | {
19 | if (string.IsNullOrWhiteSpace(keyName))
20 | throw new ArgumentException("Key name must be a non-empty string.", nameof(keyName));
21 |
22 | var iniKey = new ConfigKeyValue(keyName, parent.Settings.KeyValueSeparator, defaultValue, -1);
23 | var key = parent.fileHeader.Section.Keys.FirstOrDefault(k => Equals(keyName, k.Name));
24 | if (key != null)
25 | return (T)key.ValueRaw;
26 |
27 | parent.fileHeader.Section.AddLine(iniKey);
28 | return defaultValue;
29 | }
30 |
31 | public string GetValue(string keyName, string defaultValue = null) => GetValue(keyName, defaultValue);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/ConfigParser.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0;net40;net45
5 | ..\bin\$(Configuration)\
6 | latest
7 | Salaros.Configuration
8 | ConfigParser
9 |
10 |
11 |
12 | true
13 | true
14 | Salaros.ConfigParser
15 | ConfigParser
16 | Salaros
17 | Zhmayev Yaroslav aka Salaros
18 | Copyright 2015 (c) Salaros
19 | ConfigParser
20 | A slim, cross-platform, fully managed C# library for reading/writing .ini, .conf, .cfg etc configuration files.
21 | 0.3.7
22 | 0.3.7
23 | 0.3.7
24 | true
25 | https://raw.githubusercontent.com/salaros/config-parser/master/LICENSE
26 | https://github.com/salaros/config-parser
27 | https://github.com/salaros/config-parser
28 | Git
29 | configuration,configuration-files,file,configuration-file,config,ini,cfg,configs,conf,mono,dotnet,managed,csharp,cross-platform
30 | English
31 |
32 |
33 |
34 |
35 |
36 |
37 | /usr/lib/mono
38 | /Library/Frameworks/Mono.framework/Versions/Current/lib/mono
39 |
40 | $(MonoPath)/4.0-api
41 | $(MonoPath)/4.5-api
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | TRACE;LIBLOG_PUBLIC
55 |
56 |
57 |
58 | TRACE;DEBUG;LIBLOG_PUBLIC
59 | full
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/src/ConfigParser.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
4 |
5 |
--------------------------------------------------------------------------------
/src/ConfigParserException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Salaros.Configuration
4 | {
5 | public class ConfigParserException : Exception
6 | {
7 | ///
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// Message.
12 | /// Line number.
13 | /// Inner exception.
14 | public ConfigParserException(string message, int lineNumber = -1, Exception innterException = null)
15 | : base(message, innterException)
16 | {
17 | LineNumber = lineNumber;
18 | Message = (lineNumber < 0)
19 | ? message
20 | : $"{message}. On the line no. #{lineNumber}.";
21 | }
22 |
23 | ///
24 | /// Gets the line number.
25 | ///
26 | /// The line number.
27 | public int LineNumber { get; }
28 |
29 | ///
30 | ///
31 | /// Gets a message that describes the current exception.
32 | ///
33 | public override string Message { get; }
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/src/ConfigParserSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Text.RegularExpressions;
7 | using System.Threading;
8 |
9 | namespace Salaros.Configuration
10 | {
11 | public class ConfigParserSettings
12 | {
13 | protected Regex keyMatcher, commentMatcher, valueMatcher, arrayStartMatcher;
14 |
15 | ///
16 | /// Initializes the class.
17 | ///
18 | static ConfigParserSettings()
19 | {
20 | SectionMatcher = new Regex(@"^(?(\s+)?)\[(?.*?)\](?.*)$", RegexOptions.Compiled);
21 | }
22 |
23 | ///
24 | /// Gets the culture used for reading boolean, decimal values etc.
25 | ///
26 | ///
27 | /// The culture used for reading boolean, decimal values etc.
28 | ///
29 | public CultureInfo Culture { get; set; } = Thread.CurrentThread.CurrentCulture;
30 |
31 | ///
32 | /// Gets the multi-line value-related settings.
33 | ///
34 | ///
35 | /// The multi-line value-related settings.
36 | ///
37 | public MultiLineValues MultiLineValues { get; set; } = MultiLineValues.NotAllowed;
38 |
39 | ///
40 | /// Gets the encoding.
41 | ///
42 | ///
43 | /// The encoding.
44 | ///
45 | public Encoding Encoding { get; set; } = null;
46 |
47 | ///
48 | /// Gets or sets the boolean converter.
49 | ///
50 | ///
51 | /// The boolean converter.
52 | ///
53 | public BooleanConverter BooleanConverter { get; set; } = null;
54 |
55 | ///
56 | /// Gets the new line string.
57 | ///
58 | ///
59 | /// The new line string.
60 | ///
61 | public string NewLine { get; set; } = Environment.NewLine;
62 |
63 | ///
64 | /// Gets the key value separator.
65 | ///
66 | ///
67 | /// The key value separator.
68 | ///
69 | public string KeyValueSeparator { get; set; } = "=";
70 |
71 | ///
72 | /// Gets the comment characters.
73 | ///
74 | ///
75 | /// The comment characters.
76 | ///
77 | public string[] CommentCharacters { get; set; } = { "#", ";" };
78 |
79 | ///
80 | /// Gets the section matcher.
81 | ///
82 | ///
83 | /// The section matcher.
84 | ///
85 | internal static Regex SectionMatcher { get; set; }
86 |
87 | /// Gets the array value line matcher (matches the whitespaces at the beggining of each array value).
88 | /// The array start matcher.
89 | internal Regex ArrayStartMatcher => arrayStartMatcher ?? (arrayStartMatcher =
90 | new Regex(@"^(\s{1,})", RegexOptions.Compiled));
91 |
92 | ///
93 | /// Gets the comment matcher.
94 | ///
95 | ///
96 | /// The comment matcher.
97 | ///
98 | internal Regex CommentMatcher => commentMatcher ?? (commentMatcher =
99 | new Regex(
100 | $@"^(?(\s+)?({string.Join("|", CommentCharacters.Select(c => c.ToString()))})+(\s+)?)(?(\s+)?.*?)$",
101 | RegexOptions.Compiled));
102 |
103 | ///
104 | /// Gets the key matcher.
105 | ///
106 | ///
107 | /// The key matcher.
108 | ///
109 | internal Regex KeyMatcher => keyMatcher ?? (keyMatcher =
110 | new Regex($@"^(?.*?)(?(\s+)?{Regex.Escape(KeyValueSeparator)}(\s+)?)",
111 | RegexOptions.Compiled));
112 |
113 | ///
114 | /// Gets the value matcher.
115 | ///
116 | ///
117 | /// The value matcher.
118 | ///
119 | internal Regex ValueMatcher => valueMatcher ?? (valueMatcher = MultiLineValues.HasFlag(MultiLineValues.QuoteDelimitedValues)
120 | ? new Regex(@"^(?\"")?(?[^\""]+)(?\"")?(\s+)?$", RegexOptions.Compiled)
121 | : new Regex(@"^(?.*?)?$", RegexOptions.Compiled));
122 | }
123 |
124 | ///
125 | /// Flags / settings for handling multi-line values
126 | ///
127 | [Flags]
128 | public enum MultiLineValues
129 | {
130 | Simple = 0,
131 | NotAllowed = 1,
132 | QuoteDelimitedValues = 2,
133 | AllowValuelessKeys = 4,
134 | AllowEmptyTopSection = 8
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/src/Entries/ConfigComment.cs:
--------------------------------------------------------------------------------
1 | namespace Salaros.Configuration
2 | {
3 | public class ConfigComment : ConfigLine
4 | {
5 | protected string delimiter;
6 |
7 | ///
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// Delimiter.
12 | ///
13 | /// Line number.
14 | public ConfigComment(string delimiter = ";", string comment = "", int lineNumber = -1)
15 | : base(lineNumber)
16 | {
17 | Delimiter = delimiter;
18 | Comment = comment;
19 | }
20 |
21 | ///
22 | /// Gets the delimiter.
23 | ///
24 | /// The delimiter.
25 | public string Delimiter
26 | {
27 | get;
28 | }
29 |
30 | ///
31 | /// Gets the delimiter.
32 | ///
33 | /// The delimiter.
34 | public string Comment
35 | {
36 | get;
37 | internal set;
38 | }
39 |
40 | ///
41 | ///
42 | /// Returns a that represents the current .
43 | ///
44 | /// A that represents the current .
45 | public override string ToString()
46 | {
47 | return (string.IsNullOrWhiteSpace(Comment))
48 | ? Delimiter
49 | : $"{Delimiter}{Comment}";
50 | }
51 | }
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/src/Entries/ConfigKeyValue.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Salaros.Configuration
4 | {
5 | public class ConfigKeyValue : ConfigLine, IConfigKeyValue
6 | {
7 | protected string keyName;
8 |
9 | #region Constructors
10 |
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// Name of the key.
15 | /// The separator.
16 | /// Value.
17 | /// Line number.
18 | /// key
19 | ///
20 | public ConfigKeyValue(string keyName, string separator, T value, int lineNumber)
21 | : base(lineNumber)
22 | {
23 | if (string.IsNullOrWhiteSpace(keyName))
24 | throw new ArgumentNullException(nameof(keyName));
25 |
26 | if (separator is null)
27 | throw new ArgumentNullException(nameof(separator));
28 |
29 | this.keyName = keyName;
30 | Separator = separator;
31 | Value = value;
32 | }
33 |
34 | #endregion
35 |
36 | #region Properties
37 |
38 | ///
39 | ///
40 | /// Gets the name of the key.
41 | ///
42 | ///
43 | /// The name of the key.
44 | ///
45 | public string Name => keyName.Trim();
46 |
47 | ///
48 | /// Gets or sets the separator.
49 | ///
50 | ///
51 | /// The separator.
52 | ///
53 | public string Separator { get; }
54 |
55 | ///
56 | /// Gets the value.
57 | ///
58 | /// The value.
59 | public T Value
60 | {
61 | get => (T)ValueRaw;
62 | internal set => ValueRaw = value;
63 | }
64 |
65 | ///
66 | ///
67 | /// Gets the value raw.
68 | ///
69 | ///
70 | /// The value raw.
71 | ///
72 | public object ValueRaw
73 | {
74 | get; set;
75 | }
76 |
77 | ///
78 | ///
79 | /// Gets the name of the section.
80 | ///
81 | ///
82 | /// The name of the section.
83 | ///
84 | public string SectionName => Section?.SectionName;
85 |
86 | ///
87 | /// Gets the raw content of the line.
88 | ///
89 | ///
90 | /// The raw content of the line.
91 | ///
92 | /// ReSharper disable once InheritdocConsiderUsage
93 | public override string Content
94 | {
95 | get => ValueRaw?.ToString();
96 | set => ValueRaw = value;
97 | }
98 |
99 | #endregion
100 |
101 | #region Methods
102 |
103 | ///
104 | ///
105 | /// Returns a that represents the current .
106 | ///
107 | /// A that represents the current .
108 | public override string ToString()
109 | {
110 | return ToString(MultiLineValues.NotAllowed);
111 | }
112 |
113 | /// ReSharper disable once InheritdocInvalidUsage
114 | ///
115 | ///
116 | /// Returns a that represents this instance.
117 | ///
118 | /// The multi line settings.
119 | ///
120 | /// A that represents this instance.
121 | ///
122 | public override string ToString(MultiLineValues multiLineSettings)
123 | {
124 | switch (multiLineSettings)
125 | {
126 | case MultiLineValues.AllowValuelessKeys when string.IsNullOrWhiteSpace(Content):
127 | return keyName;
128 |
129 | case MultiLineValues.QuoteDelimitedValues:
130 | return $"{keyName}{Separator}\"{Content}\"";
131 |
132 | default:
133 | return $"{keyName}{Separator}{Content}";
134 | }
135 | }
136 |
137 | #endregion
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/src/Entries/ConfigLine.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 |
3 | namespace Salaros.Configuration
4 | {
5 | public class ConfigLine : IConfigLine
6 | {
7 | protected int lineNumber;
8 | private string lineContent;
9 | internal static readonly Regex IndentationMatcher;
10 |
11 | #region Constructor
12 |
13 | static ConfigLine()
14 | {
15 | IndentationMatcher = new Regex(@"^(\s+)", RegexOptions.Compiled | RegexOptions.Singleline);
16 | }
17 |
18 | ///
19 | /// Initializes a new instance of the class.
20 | ///
21 | /// Line number.
22 | /// Raw line content.
23 | public ConfigLine(int lineNumber = -1, string lineContent = "")
24 | {
25 | this.lineContent = lineContent;
26 | this.lineNumber = lineNumber;
27 | }
28 |
29 | #endregion
30 |
31 | #region Properties
32 |
33 | #region IConfigLine implementation
34 |
35 | ///
36 | ///
37 | /// Gets the line number.
38 | ///
39 | /// The line number.
40 | public virtual int LineNumber
41 | {
42 | get
43 | {
44 | if (lineNumber < 0 && Section != null)
45 | lineNumber = Section.GetLineNumber(this);
46 |
47 | return lineNumber;
48 | }
49 | }
50 |
51 | ///
52 | ///
53 | /// Gets the raw content of the line.
54 | ///
55 | /// The raw content of the line.
56 | public virtual string Content
57 | {
58 | get => lineContent;
59 | set => lineContent = value;
60 | }
61 |
62 | #endregion
63 |
64 | ///
65 | ///
66 | /// Gets the section.
67 | ///
68 | ///
69 | /// The section.
70 | ///
71 | public ConfigSection Section
72 | {
73 | get; internal set;
74 | }
75 |
76 | ///
77 | ///
78 | /// Gets the indentation.
79 | ///
80 | ///
81 | /// The indentation.
82 | ///
83 | public string Indentation => IndentationMatcher?.Match(ToString()).Value;
84 |
85 | #endregion
86 |
87 | #region Methods
88 |
89 | ///
90 | /// Returns a that represents the current .
91 | ///
92 | /// A that represents the current .
93 | public override string ToString()
94 | {
95 | return Content;
96 | }
97 |
98 | ///
99 | ///
100 | /// Returns a that represents this instance.
101 | ///
102 | /// The multi line settings.
103 | ///
104 | /// A that represents this instance.
105 | ///
106 | public virtual string ToString(MultiLineValues multiLineSettings)
107 | {
108 | return ToString();
109 | }
110 |
111 | #endregion
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/Entries/ConfigSection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Linq;
5 |
6 | namespace Salaros.Configuration
7 | {
8 | public class ConfigSection : ConfigSectionBase, IConfigLine
9 | {
10 | protected int lineNumber;
11 | protected string sectionName, comment;
12 |
13 | #region Constructors
14 |
15 | ///
16 | /// Initializes a new instance of the class.
17 | ///
18 | /// Section name.
19 | /// Line number.
20 | /// The indentation.
21 | /// The comment.
22 | /// sectionName
23 | ///
24 | public ConfigSection(string sectionName, int lineNumber = -1, string indentation = "", string comment = "")
25 | : this()
26 | {
27 | this.sectionName = sectionName ?? throw new ArgumentNullException(nameof(sectionName));
28 | this.lineNumber = lineNumber;
29 | this.comment = comment;
30 |
31 | Indentation = indentation;
32 | }
33 |
34 | ///
35 | /// Initializes a new instance of the class.
36 | ///
37 | internal ConfigSection()
38 | : base()
39 | {
40 | sectionName = string.Empty;
41 | lineNumber = 0;
42 | }
43 |
44 | #endregion
45 |
46 | #region Methods
47 |
48 | ///
49 | /// Returns a that represents the current .
50 | ///
51 | /// A that represents the current .
52 | public override string ToString() => Content;
53 |
54 | ///
55 | /// Adds a configuration file line.
56 | ///
57 | /// The configuration file line to add.
58 | internal override void AddLine(ConfigLine configLine)
59 | {
60 | base.AddLine(configLine);
61 | configLine.Section = this;
62 | }
63 |
64 | ///
65 | ///
66 | /// Returns a that represents this instance.
67 | ///
68 | /// The multi line settings.
69 | ///
70 | /// A that represents this instance.
71 | ///
72 | public string ToString(MultiLineValues multiLineSettings) => ToString();
73 |
74 | #endregion
75 |
76 | #region Properties
77 |
78 | #region IConfigLine implementation
79 |
80 | ///
81 | ///
82 | /// Gets the section.
83 | ///
84 | ///
85 | /// The section.
86 | ///
87 | public ConfigSection Section => this;
88 |
89 |
90 | ///
91 | ///
92 | /// Gets the line number.
93 | ///
94 | /// The line number.
95 | public virtual int LineNumber => lineNumber;
96 |
97 | #endregion
98 |
99 | ///
100 | /// Gets the name of the section.
101 | ///
102 | /// The name of the section.
103 | public string SectionName => sectionName;
104 |
105 | ///
106 | /// Gets the keys.
107 | ///
108 | /// The keys.
109 | public
110 | #if NET40
111 | ReadOnlyCollection Keys
112 | #else
113 | IReadOnlyCollection Keys
114 | #endif
115 | => new ReadOnlyCollection(lines.OfType().OrderBy(k => k.LineNumber).ToList());
116 |
117 | ///
118 | /// Gets all the lines of the given section.
119 | ///
120 | /// The lines.
121 | public override
122 | #if NET40
123 | ReadOnlyCollection Lines
124 | #else
125 | IReadOnlyCollection Lines
126 | #endif
127 | {
128 | get
129 | {
130 | var allLines = (string.IsNullOrWhiteSpace(sectionName))
131 | ? new List()
132 | : new List { this };
133 | allLines.AddRange(lines.Cast().OrderBy(k => k.LineNumber));
134 | return new ReadOnlyCollection(allLines);
135 | }
136 | }
137 |
138 | ///
139 | /// Gets the raw content of the line.
140 | ///
141 | ///
142 | /// The raw content of the line.
143 | ///
144 | /// ReSharper disable once InheritdocConsiderUsage
145 | public string Content => string.IsNullOrWhiteSpace(sectionName)
146 | ? string.Empty
147 | : $"{Indentation}[{sectionName}]{comment}";
148 |
149 | ///
150 | ///
151 | /// Gets the indentation.
152 | ///
153 | ///
154 | /// The indentation.
155 | ///
156 | ///
157 | public string Indentation
158 | {
159 | get;
160 | }
161 |
162 | #endregion
163 |
164 | #region Indexing
165 |
166 | ///
167 | /// Gets the with the specified key name.
168 | ///
169 | ///
170 | /// The .
171 | ///
172 | /// Name of the key.
173 | /// Key value.
174 | public override string this[string keyName]
175 | {
176 | get
177 | {
178 | return (keyName is null)
179 | ? null
180 | : Keys
181 | ?.FirstOrDefault(s => keyName.Equals(s.Name, StringComparison.InvariantCultureIgnoreCase))
182 | ?.ValueRaw as string;
183 | }
184 | }
185 |
186 | #endregion
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/src/Entries/ConfigSectionBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace Salaros.Configuration
8 | {
9 | public abstract class ConfigSectionBase
10 | {
11 | protected List lines;
12 |
13 | protected ConfigSectionBase()
14 | {
15 | lines = new List();
16 | }
17 |
18 | #region Properties
19 |
20 | ///
21 | /// Gets all the lines of the given section.
22 | ///
23 | /// The lines.
24 | public abstract
25 | #if NET40
26 | ReadOnlyCollection Lines
27 | #else
28 | IReadOnlyCollection Lines
29 | #endif
30 | { get; }
31 |
32 | public abstract string this[string value] { get; }
33 |
34 | #endregion Properties
35 |
36 | #region Methods
37 |
38 | ///
39 | /// Gets the line number of the given line.
40 | ///
41 | /// The line number.
42 | /// Line.
43 | internal int GetLineNumber(ConfigLine line)
44 | {
45 | if (line == null)
46 | throw new ArgumentNullException(nameof(line));
47 |
48 | return (lines == null || !lines.Any())
49 | ? -1
50 | : lines.IndexOf(line);
51 | }
52 |
53 | ///
54 | /// Adds a configuration file line.
55 | ///
56 | /// The configuration file line to add.
57 | internal virtual void AddLine(ConfigLine configLine)
58 | {
59 | lines.Add(configLine);
60 | }
61 |
62 | #endregion Methods
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Entries/IConfigKeyValue.cs:
--------------------------------------------------------------------------------
1 | namespace Salaros.Configuration
2 | {
3 | public interface IConfigKeyValue : IConfigLine
4 | {
5 | ///
6 | /// Gets the name of the key.
7 | ///
8 | ///
9 | /// The name of the key.
10 | ///
11 | string Name { get; }
12 |
13 | ///
14 | /// Gets the value raw.
15 | ///
16 | ///
17 | /// The value raw.
18 | ///
19 | object ValueRaw { get; set; }
20 |
21 | ///
22 | /// Gets the name of the section.
23 | ///
24 | ///
25 | /// The name of the section.
26 | ///
27 | string SectionName { get; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Entries/IConfigLine.cs:
--------------------------------------------------------------------------------
1 | namespace Salaros.Configuration
2 | {
3 | public interface IConfigLine
4 | {
5 | ///
6 | /// Gets the line number.
7 | ///
8 | /// The line number.
9 | int LineNumber { get; }
10 |
11 | ///
12 | /// Gets the raw content of the line.
13 | ///
14 | /// The raw content of the line.
15 | string Content { get; }
16 |
17 | ///
18 | /// Gets the section.
19 | ///
20 | ///
21 | /// The section.
22 | ///
23 | ConfigSection Section { get; }
24 |
25 | ///
26 | /// Gets the indentation.
27 | ///
28 | ///
29 | /// The indentation.
30 | ///
31 | string Indentation { get; }
32 |
33 | ///
34 | /// Returns a that represents this instance.
35 | ///
36 | /// The multi line settings.
37 | ///
38 | /// A that represents this instance.
39 | ///
40 | string ToString(MultiLineValues multiLineSettings);
41 | }
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/src/Helpers/FileInfoExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Text;
3 | using System.Text.RegularExpressions;
4 |
5 | // ReSharper disable once CheckNamespace
6 |
7 | namespace System.IO
8 | {
9 | ///
10 | /// Extensions for class
11 | ///
12 | public static class FileInfoExtensions
13 | {
14 | public static readonly Regex UnicodeLetters;
15 | public static readonly Regex AnsiLatin1Mangled;
16 |
17 | ///
18 | /// Initializes the class.
19 | ///
20 | static FileInfoExtensions()
21 | {
22 | AnsiLatin1Mangled = new Regex(@"[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿŸ]", RegexOptions.Compiled | RegexOptions.Multiline);
23 | UnicodeLetters = new Regex(@"\p{L}", RegexOptions.Compiled | RegexOptions.Multiline);
24 | }
25 |
26 | ///
27 | /// Tries the get file encoding.
28 | ///
29 | /// The file.
30 | /// The encoding.
31 | ///
32 | /// file
33 | public static bool TryGetEncoding(this FileInfo file, out Encoding encoding)
34 | {
35 | if (null == file || !file.Exists)
36 | throw new ArgumentException($"{nameof(file)} must be a valid path to a file!");
37 |
38 | var bytes = new byte[10];
39 | using (var fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
40 | {
41 | fs.Read(bytes, 0, 10);
42 | #if !NETSTANDARD1_6
43 | fs.Close();
44 | #endif
45 | }
46 |
47 | switch (bytes)
48 | {
49 | case var utf7 when 0x2B == utf7[0] && 0x2F == utf7[1] && 0x76 == utf7[2]:
50 | encoding = Encoding.UTF7;
51 | break;
52 |
53 | case var utf32 when 0x00 == utf32[0] && 0x00 == utf32[1] && 0xFE == utf32[2] && 0xFF == utf32[3]:
54 | encoding = Encoding.GetEncoding(12001); // UTF-32, big endian byte order; available only to managed applications
55 | break;
56 |
57 | case var utf32 when 0xFF == utf32[0] && 0xFE == utf32[1] && 0x00 == utf32[2] && 0x00 == utf32[3]:
58 | encoding = Encoding.GetEncoding(12000); // UTF-32, little endian byte order; available only to managed applications
59 | break;
60 |
61 | case var unicode when 0xFE == unicode[0] && 0xFF == unicode[1]:
62 | encoding = Encoding.GetEncoding(1201); // 1201 unicodeFFFE Unicode (UTF-16BE aka Unicode big endian)
63 | break;
64 |
65 | case var unicode when 0xFF == unicode[0] && 0xFE == unicode[1]:
66 | encoding = Encoding.GetEncoding(1200); // 1200 UTF-16 Unicode (UTF-16LE aka Unicode little endian)
67 | break;
68 |
69 | case var utf8 when HasBomMarker(utf8):
70 | encoding = new UTF8Encoding(true); // UTF-8 with BOM
71 | break;
72 |
73 | case var _ when file.IsInUtf8():
74 | encoding = new UTF8Encoding(false); // UTF-8 without BOM
75 | break;
76 |
77 | case var _ when file.IsInAnsiLatin1():
78 | encoding = Encoding.GetEncoding(1252); // ANSI Latin
79 | break;
80 |
81 | default:
82 | encoding = null;
83 | return false;
84 | }
85 |
86 | return true;
87 | }
88 |
89 | ///
90 | /// Gets the encoding.
91 | ///
92 | /// The file.
93 | /// if set to true [throws an exception if encoding is not detected].
94 | ///
95 | /// Detected file encoding or null detection failed
96 | ///
97 | /// file
98 | ///
99 | public static Encoding GetEncoding(this FileInfo file, bool throwIfNotDetected = false)
100 | {
101 | if (null == file || !file.Exists)
102 | throw new ArgumentException($"{nameof(file)} must be a valid path to a file!");
103 |
104 | var encoding = (file.TryGetEncoding(out var fileEncoding))
105 | ? fileEncoding
106 | : null;
107 |
108 | if (null == encoding && throwIfNotDetected)
109 | {
110 | throw new InvalidDataException(
111 | $"Unable to detect encoding automatically of the following shared parameter file: {file.FullName}. " +
112 | "Most likely it's a non-Latin ANSI, e.g. ANSI Cyrillic, Hebrew, Arabic, Greek, Turkish, Vietnamese etc"
113 | );
114 | }
115 |
116 | return encoding;
117 | }
118 |
119 | ///
120 | /// Determines whether [is in ANSI latin1] [the specified thresh hold].
121 | ///
122 | /// The file.
123 | /// The threshold of mangled characters.
124 | ///
125 | /// true if [file is ANSI Latin1-encoded] and [the number of mangled characters is lower than specified threshold]; otherwise, false.
126 | ///
127 | /// file
128 | public static bool IsInAnsiLatin1(this FileInfo file, double mangledCharThreshold = 60.0)
129 | {
130 | if (null == file || !file.Exists)
131 | throw new ArgumentException($"{nameof(file)} must be a valid path to a file!");
132 |
133 | var ansiLatin1Encoding = Encoding.GetEncoding(1252);
134 | var ansiText = File.ReadAllText(file.FullName, ansiLatin1Encoding);
135 |
136 | var unicodeLettersFound = UnicodeLetters.Matches(ansiText);
137 | var ansiMangledFound = AnsiLatin1Mangled.Matches(ansiText);
138 | var matchRate = ansiMangledFound.Count * 100 / unicodeLettersFound.Count;
139 | return (matchRate <= mangledCharThreshold);
140 | }
141 |
142 | ///
143 | /// Determines whether [has UTF-8 BOM marker].
144 | ///
145 | /// The file.
146 | ///
147 | /// true if [the specified file] [has UTF-8 BOM marker]; otherwise, false.
148 | ///
149 | /// file
150 | public static bool HasBomMarker(this FileInfo file)
151 | {
152 | if (null == file || !file.Exists)
153 | throw new ArgumentException($"{nameof(file)} must be a valid path to a file!");
154 |
155 | var buffer = new byte[10];
156 | using (var fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
157 | {
158 | fs.Read(buffer, 0, 10);
159 | #if !NETSTANDARD1_6
160 | fs.Close();
161 | #endif
162 | }
163 |
164 | return 0xEF == buffer[0] && 0xBB == buffer[1] && 0xBF == buffer[2];
165 | }
166 |
167 | ///
168 | /// Determines whether [has UTF-8 BOM marker] [the specified bytes].
169 | ///
170 | /// The bytes.
171 | ///
172 | /// true if [the specified bytes] [has UTF-8 BOM marker]; otherwise, false.
173 | ///
174 | /// bytes
175 | public static bool HasBomMarker(byte[] bytes)
176 | {
177 | if (bytes == null || !bytes.Any())
178 | throw new ArgumentException($"{nameof(bytes)} must be a non-empty array of bytes!");
179 |
180 | return 0xEF == bytes[0] && 0xBB == bytes[1] && 0xBF == bytes[2];
181 | }
182 |
183 | ///
184 | /// Determines whether [is in UTF-8].
185 | ///
186 | /// The file.
187 | ///
188 | /// true if[the specified file] [is in UTF-8]; otherwise, false.
189 | ///
190 | /// file
191 | public static bool IsInUtf8(this FileInfo file)
192 | {
193 | if (null == file || !file.Exists)
194 | throw new ArgumentException($"{nameof(file)} must be a valid path to a file!");
195 |
196 | try
197 | {
198 | using (var fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
199 | {
200 | using var streamReader = new StreamReader(fileStream, new UTF8Encoding(file.HasBomMarker(), true), true);
201 | streamReader.ReadToEnd();
202 | }
203 | return true;
204 | }
205 | catch (DecoderFallbackException)
206 | {
207 | return false;
208 | }
209 | }
210 |
211 | ///
212 | /// Detects the most used new line string / character in a file.
213 | ///
214 | /// The file information.
215 | /// The configuration file.
216 | ///
217 | /// configFile
218 | public static string DetectNewLine(this FileInfo fileInfo, string configFile)
219 | {
220 | if (string.IsNullOrWhiteSpace(configFile) || !File.Exists(configFile))
221 | throw new ArgumentNullException(nameof(configFile));
222 |
223 | configFile = File.ReadAllText(configFile);
224 |
225 | var windowsEndings = Regex.Matches(configFile, "\r\n").Count;
226 | var unixEndings = Regex.Matches(configFile, "\n").Count;
227 | var oldMacEndings = Regex.Matches(configFile, "\r").Count;
228 |
229 | return windowsEndings >= unixEndings && windowsEndings >= oldMacEndings
230 | ? "\r\n"
231 | : unixEndings > windowsEndings && unixEndings > oldMacEndings
232 | ? "\n"
233 | : oldMacEndings > windowsEndings && oldMacEndings > unixEndings
234 | ? "\r"
235 | : Environment.NewLine;
236 | }
237 | }
238 | }
239 |
--------------------------------------------------------------------------------
/src/Helpers/YesNoConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Globalization;
4 |
5 | namespace Salaros.Configuration
6 | {
7 | public class YesNoConverter : BooleanConverter
8 | {
9 | protected readonly string yes, no;
10 |
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The yes.
15 | /// The no.
16 | ///
17 | /// yes
18 | /// or
19 | /// no
20 | /// or
21 | ///
22 | ///
23 | public YesNoConverter(string yes = "yes", string no = "no")
24 | {
25 | if (string.IsNullOrWhiteSpace(yes)) throw new ArgumentException(nameof(yes));
26 | if (string.IsNullOrWhiteSpace(no)) throw new ArgumentException(nameof(no));
27 | if (Equals(yes, no))
28 | throw new ArgumentException($"Yes ({yes}) and No ({no}) values must be two different values!");
29 |
30 | this.yes = yes;
31 | this.no = no;
32 | }
33 |
34 | ///
35 | ///
36 | /// Converts the given value object to the specified type, using the specified context and culture information.
37 | ///
38 | /// An that provides a format context.
39 | /// A . If is passed, the current culture is assumed.
40 | /// The to convert.
41 | /// The to convert the parameter to.
42 | ///
43 | /// An that represents the converted value.
44 | ///
45 | public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
46 | {
47 | return value is bool boolean && destinationType == typeof(string)
48 | ? boolean ? yes : no
49 | : base.ConvertTo(context, culture, value, destinationType);
50 | }
51 |
52 | ///
53 | ///
54 | /// Converts the given value object to a Boolean object.
55 | ///
56 | /// An that provides a format context.
57 | /// A that specifies the culture to which to convert.
58 | /// The to convert.
59 | ///
60 | /// An that represents the converted .
61 | ///
62 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
63 | {
64 | var booleanText = value as string;
65 | if (no.Equals(booleanText, StringComparison.OrdinalIgnoreCase))
66 | return false;
67 |
68 | if (yes.Equals(booleanText, StringComparison.OrdinalIgnoreCase))
69 | return true;
70 |
71 | return null;
72 | }
73 |
74 | ///
75 | /// Gets the value of Yes / True.
76 | ///
77 | ///
78 | /// The yes.
79 | ///
80 | public string Yes => yes;
81 |
82 | ///
83 | /// Gets the value of No / False.
84 | ///
85 | ///
86 | /// The no.
87 | ///
88 | public string No => no;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/tests/ConfigParser.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0;net452
5 | false
6 | Salaros.Configuration.Tests
7 | portable
8 |
9 |
10 |
11 | ..\bin\$(Configuration)\
12 | Salaros
13 | ConfigParser
14 | Zhmayev Yaroslav aka Salaros
15 |
16 |
17 |
18 | 2.3.*
19 | 2.4.*
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | all
30 | runtime; build; native; contentfiles; analyzers; buildtransitive
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | PreserveNewest
50 |
51 |
52 |
53 |
54 |
55 | PreserveNewest
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/tests/ConfigParser.Tests.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
--------------------------------------------------------------------------------
/tests/ConfigParserTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Threading;
4 | using Xunit;
5 |
6 | namespace Salaros.Configuration.Tests
7 | {
8 | public class ConfigParserTests
9 | {
10 | [Fact]
11 | public void ExistingFileIsUpdatedCorrectly()
12 | {
13 | var configFilePathTmp = Path.GetTempFileName();
14 | File.WriteAllLines(configFilePathTmp, new[]
15 | {
16 | "[Settings]",
17 | "Recno = chocolate"
18 | });
19 |
20 | var configFile = new ConfigParser(configFilePathTmp);
21 | configFile.SetValue("Settings", "Recno", "123");
22 | configFile.Save(configFilePathTmp);
23 |
24 | Assert.Equal("[Settings]\r\nRecno = 123", configFile.ToString());
25 | }
26 |
27 | [Fact]
28 | public void FileCanBeSavedToTheSamePath()
29 | {
30 | var configFilePathTmp = Path.GetTempFileName();
31 | File.WriteAllLines(configFilePathTmp, new[]
32 | {
33 | "[Baz]",
34 | "Foo = bar"
35 | });
36 | var dateModifiedOld = File.GetLastWriteTime(configFilePathTmp);
37 |
38 | var configFile = new ConfigParser(configFilePathTmp);
39 | configFile.Save();
40 |
41 | Assert.True(File.GetLastWriteTime(configFilePathTmp).Ticks >= dateModifiedOld.Ticks);
42 | }
43 |
44 | [Fact]
45 | public void FileCanBeSavedToNewPath()
46 | {
47 | var configFilePathTmp = Path.GetTempFileName();
48 | File.WriteAllLines(configFilePathTmp, new[]
49 | {
50 | "[Baz]",
51 | "Foo = bar"
52 | });
53 |
54 | var configFile = new ConfigParser(configFilePathTmp);
55 | var configFilePathTmpNew = Path.GetTempFileName();
56 | configFile.Save(configFilePathTmpNew);
57 |
58 | Assert.True(File.Exists(configFilePathTmpNew));
59 | }
60 |
61 | [Fact]
62 | public void ArrayIsReadCorrectly()
63 | {
64 | // Set up
65 | var settings = new ConfigParserSettings { MultiLineValues = MultiLineValues.Simple | MultiLineValues.QuoteDelimitedValues };
66 | var configFile = new ConfigParser(
67 | @"[Advanced]
68 | Select =
69 | select * from
70 | from table
71 | where ID = '5'
72 | ",
73 | settings);
74 |
75 | // Act
76 | var arrayValues = configFile.GetArrayValue("Advanced", "Select");
77 |
78 | // Assert
79 | Assert.Equal(3, arrayValues?.Length ?? 0);
80 | Assert.Equal("select * from", arrayValues[0]);
81 | Assert.Equal("from table", arrayValues[1]);
82 | Assert.Equal("where ID = '5'", arrayValues[2]);
83 | }
84 |
85 | [Fact]
86 | public void JoinMultilineValueWorks()
87 | {
88 | // Set up
89 | var settings = new ConfigParserSettings { MultiLineValues = MultiLineValues.Simple };
90 | var configFile = new ConfigParser(
91 | @"[Advanced]
92 | ExampleValue = Lorem ipsum dolor sit amet
93 | consectetur adipiscing elit
94 | sed do eiusmod tempor incididunt
95 | ",
96 | settings);
97 |
98 | // Act
99 | var multiLineJoint = configFile.JoinMultilineValue("Advanced", "ExampleValue", " ");
100 |
101 | // Assert
102 | Assert.Equal("Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt", multiLineJoint);
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/tests/JsonHelpers/ConfigParserSettingsResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Text;
4 | using Koopman.CheckPoint.Json;
5 | using Newtonsoft.Json.Serialization;
6 |
7 | namespace Salaros.Configuration.Tests
8 | {
9 | internal class ConfigParserSettingsResolver : DefaultContractResolver
10 | {
11 | ///
12 | ///
13 | /// Creates a for the given type.
14 | ///
15 | /// Type of the object.
16 | ///
17 | /// A for the given type.
18 | ///
19 | protected override JsonPrimitiveContract CreatePrimitiveContract(Type objectType)
20 | {
21 | var contract = base.CreatePrimitiveContract(objectType);
22 | if (objectType == typeof(MultiLineValues))
23 | {
24 | contract.Converter = new EnumConverter();
25 | }
26 | return contract;
27 | }
28 |
29 | ///
30 | ///
31 | /// Creates a for the given type.
32 | ///
33 | /// Type of the object.
34 | ///
35 | /// A for the given type.
36 | ///
37 | protected override JsonObjectContract CreateObjectContract(Type objectType)
38 | {
39 | if (objectType == null) throw new ArgumentNullException(nameof(objectType));
40 |
41 | var contract = base.CreateObjectContract(objectType);
42 | switch (objectType)
43 | {
44 | case var _ when objectType == typeof(Encoding) || objectType.IsSubclassOf(typeof(Encoding)):
45 | contract.Converter = new EncodingConverter();
46 | break;
47 |
48 | case var _ when objectType == typeof(CultureInfo):
49 | contract.Converter = new CultureConverter();
50 | break;
51 | }
52 |
53 | return contract;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests/JsonHelpers/CultureConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using Newtonsoft.Json;
4 |
5 | namespace Salaros.Configuration.Tests
6 | {
7 | public class CultureConverter : JsonConverter
8 | {
9 | ///
10 | ///
11 | /// Determines whether this instance can convert the specified object type.
12 | ///
13 | /// Type of the object.
14 | ///
15 | /// true if this instance can convert the specified object type; otherwise, false.
16 | ///
17 | public override bool CanConvert(Type objectType)
18 | {
19 | return typeof(CultureInfo).IsAssignableFrom(objectType);
20 | }
21 |
22 | ///
23 | ///
24 | /// Writes the JSON representation of the object.
25 | ///
26 | /// The to write to.
27 | /// The value.
28 | /// The calling serializer.
29 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
30 | {
31 | writer.WriteValue(((CultureInfo)value).Name);
32 | }
33 |
34 | ///
35 | ///
36 | /// Reads the JSON representation of the object.
37 | ///
38 | /// The to read from.
39 | /// Type of the object.
40 | /// The existing value of object being read.
41 | /// The calling serializer.
42 | ///
43 | /// The object value.
44 | ///
45 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
46 | {
47 | return string.IsNullOrWhiteSpace(reader?.Value?.ToString())
48 | ? CultureInfo.InvariantCulture
49 | : new CultureInfo((string)reader.Value);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tests/JsonHelpers/EncodingConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Text;
4 | using Newtonsoft.Json;
5 |
6 | namespace Salaros.Configuration.Tests
7 | {
8 | public class EncodingConverter : JsonConverter
9 | {
10 | ///
11 | ///
12 | /// Determines whether this instance can convert the specified object type.
13 | ///
14 | /// Type of the object.
15 | ///
16 | /// true if this instance can convert the specified object type; otherwise, false.
17 | ///
18 | public override bool CanConvert(Type objectType)
19 | {
20 | return typeof(Encoding).IsAssignableFrom(objectType);
21 | }
22 |
23 | ///
24 | ///
25 | /// Writes the JSON representation of the object.
26 | ///
27 | /// The to write to.
28 | /// The value.
29 | /// The calling serializer.
30 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
31 | {
32 | var json = JsonConvert.SerializeObject((EncodingPortable)(Encoding)value);
33 | writer.WriteRawValue(json);
34 | }
35 |
36 | ///
37 | ///
38 | /// Reads the JSON representation of the object.
39 | ///
40 | /// The to read from.
41 | /// Type of the object.
42 | /// The existing value of object being read.
43 | /// The calling serializer.
44 | ///
45 | /// The object value.
46 | ///
47 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
48 | {
49 | if (!(reader is JsonTextReader))
50 | return null;
51 |
52 | var encodingPortable = new EncodingPortable();
53 | while (reader.Read())
54 | {
55 | switch (reader.Value)
56 | {
57 | case nameof(EncodingPortable.CodePage) when reader.Read():
58 | encodingPortable.CodePage = int.Parse(reader.Value?.ToString());
59 | break;
60 |
61 | case nameof(EncodingPortable.WithPreamble) when reader.Read():
62 | encodingPortable.WithPreamble = bool.Parse(reader.Value?.ToString());
63 | break;
64 |
65 | case null:
66 | return (Encoding)encodingPortable;
67 | }
68 | }
69 |
70 | return null;
71 | }
72 |
73 | internal class EncodingPortable
74 | {
75 | public int CodePage { get; internal set; } = -1;
76 |
77 | public bool WithPreamble { get; internal set; } = true;
78 |
79 | // User-defined conversion from Digit to double
80 | public static implicit operator EncodingPortable(Encoding encoding)
81 | {
82 | if (encoding == null) throw new ArgumentNullException(nameof(encoding));
83 |
84 | return new EncodingPortable
85 | {
86 | CodePage = encoding.CodePage,
87 | WithPreamble = encoding.GetPreamble()?.Any() ?? false
88 | };
89 | }
90 | // User-defined conversion from double to Digit
91 | public static implicit operator Encoding(EncodingPortable encodingPortable)
92 | {
93 | if (encodingPortable == null) throw new ArgumentNullException(nameof(encodingPortable));
94 |
95 | switch (encodingPortable.CodePage)
96 | {
97 | case 65001:
98 | return new UTF8Encoding(encodingPortable.WithPreamble);
99 |
100 | default:
101 | return Encoding.GetEncoding(encodingPortable.CodePage);
102 | }
103 | }
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/tests/JsonHelpers/EnumConverter.cs:
--------------------------------------------------------------------------------
1 | // MIT License
2 | //
3 | // Copyright (c) 2018 Tim Koopman
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6 | // associated documentation files (the "Software"), to deal in the Software without restriction,
7 | // including without limitation the rights to use, copy, modify, merge, publish, distribute,
8 | // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15 | // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18 | // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | // Copyright (c) 2007 James Newton-King
21 | //
22 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
23 | // associated documentation files (the "Software"), to deal in the Software without restriction,
24 | // including without limitation the rights to use, copy, modify, merge, publish, distribute,
25 | // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
26 | // furnished to do so, subject to the following conditions:
27 | //
28 | // The above copyright notice and this permission notice shall be included in all copies or
29 | // substantial portions of the Software.
30 | //
31 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
32 | // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
34 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
35 | // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 |
37 | using Newtonsoft.Json;
38 | using System;
39 | using System.Collections.Generic;
40 | using System.Linq;
41 | using System.Reflection;
42 | using System.Runtime.Serialization;
43 | using System.Text.RegularExpressions;
44 |
45 | // ReSharper disable once CheckNamespace
46 |
47 | namespace Koopman.CheckPoint.Json
48 | {
49 | ///
50 | ///
51 | /// Converts an to and from its name string value.
52 | ///
53 | internal class EnumConverter : JsonConverter
54 | {
55 | #region Constructors
56 |
57 | ///
58 | /// Initializes a new instance of the class.
59 | ///
60 | public EnumConverter(
61 | StringCases outputCase,
62 | string outputSplitWords,
63 | OutputArrayOptions outputArray,
64 | bool nullAsZero)
65 | {
66 | OutputArray = outputArray;
67 | OutputCase = outputCase;
68 | OutputSplitWords = outputSplitWords;
69 | NullAsZero = nullAsZero;
70 | }
71 |
72 | public EnumConverter() : this(StringCases.NoChange, null, OutputArrayOptions.Auto, false)
73 | {
74 | }
75 |
76 | public EnumConverter(StringCases outputCase) : this(outputCase, null, OutputArrayOptions.Auto, false)
77 | {
78 | }
79 |
80 | public EnumConverter(StringCases outputCase, string outputSplitWords) : this(outputCase, outputSplitWords, OutputArrayOptions.Auto, false)
81 | {
82 | }
83 |
84 | #endregion Constructors
85 |
86 | #region Enums
87 |
88 | public enum OutputArrayOptions
89 | {
90 | Auto,
91 | Yes,
92 | No
93 | }
94 |
95 | // String case to write values in.
96 | public enum StringCases
97 | {
98 | NoChange,
99 | Uppercase,
100 | Lowercase
101 | }
102 |
103 | #endregion Enums
104 |
105 | #region Properties
106 |
107 | public bool NullAsZero { get; }
108 | public OutputArrayOptions OutputArray { get; }
109 | public StringCases OutputCase { get; }
110 | public string OutputSplitWords { get; }
111 |
112 | #endregion Properties
113 |
114 | #region Methods
115 |
116 | ///
117 | ///
118 | /// Determines whether this instance can convert the specified object type.
119 | ///
120 | /// Type of the object.
121 | ///
122 | /// true if this instance can convert the specified object type; otherwise, false.
123 | ///
124 | public override bool CanConvert(Type objectType)
125 | {
126 | var t = (GetIsNullable(objectType))
127 | ? Nullable.GetUnderlyingType(objectType)
128 | : objectType;
129 |
130 | return t.GetTypeInfo().IsEnum;
131 | }
132 |
133 | ///
134 | /// Reads the JSON representation of the object.
135 | ///
136 | /// The to read from.
137 | /// Type of the object.
138 | /// The existing value of object being read.
139 | /// The calling serializer.
140 | /// The object value.
141 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
142 | {
143 | bool isNullable = GetIsNullable(objectType);
144 | var t = isNullable ? Nullable.GetUnderlyingType(objectType) : objectType;
145 |
146 | if (reader.TokenType == JsonToken.Null)
147 | {
148 | if (NullAsZero)
149 | return 0;
150 |
151 | if (!isNullable)
152 | throw new JsonSerializationException($"Cannot convert null value to {objectType}.");
153 |
154 | return null;
155 | }
156 |
157 | try
158 | {
159 | if (reader.TokenType == JsonToken.String)
160 | {
161 | string enumText = reader.Value.ToString();
162 |
163 | if (enumText == string.Empty)
164 | {
165 | if (NullAsZero)
166 | return 0;
167 |
168 | if (isNullable)
169 | return null;
170 | }
171 |
172 | return DeserializeValue(enumText, t);
173 | }
174 |
175 | if (reader.TokenType == JsonToken.StartArray)
176 | {
177 | int result = 0;
178 | reader.Read();
179 | while (reader.TokenType == JsonToken.String)
180 | {
181 | string enumText = reader.Value.ToString();
182 | if (enumText != string.Empty)
183 | {
184 | result |= (int)DeserializeValue(enumText, t);
185 | }
186 | reader.Read();
187 | }
188 | return result;
189 | }
190 | }
191 | catch (Exception)
192 | {
193 | throw new JsonSerializationException($"Error converting value {reader.Value} to type '{objectType}'.");
194 | }
195 |
196 | throw new JsonSerializationException($"Error converting value {reader.Value} to type '{objectType}'.");
197 | }
198 |
199 | ///
200 | /// Writes the JSON representation of the object.
201 | ///
202 | /// The to write to.
203 | /// The value.
204 | /// The calling serializer.
205 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
206 | {
207 | bool isNullable = GetIsNullable(value.GetType());
208 | var t = isNullable ? Nullable.GetUnderlyingType(value.GetType()) : value.GetType();
209 |
210 | bool asArray = (OutputArray == OutputArrayOptions.Auto) ?
211 | t.GetTypeInfo().GetCustomAttribute(typeof(FlagsAttribute)) != null :
212 | OutputArray == OutputArrayOptions.Yes;
213 |
214 | var e = (Enum)value;
215 | if (asArray)
216 | {
217 | writer.WriteStartArray();
218 |
219 | if (value != null)
220 | {
221 | var values = new List(); string[] flags = t.GetTypeInfo().GetEnumNames();
222 | foreach (string flag in flags)
223 | {
224 | var flagEnum = (Enum)Enum.Parse(t, flag);
225 | var flagInfo = t.GetTypeInfo().GetMember(flag);
226 | var ignore = flagInfo[0].GetCustomAttribute(typeof(JsonIgnoreAttribute)) != null;
227 | if (!ignore && e.HasFlag(flagEnum))
228 | writer.WriteValue(SerializeValue(flag, t));
229 | }
230 | }
231 |
232 | writer.WriteEndArray();
233 | }
234 | else if (value == null)
235 | writer.WriteNull();
236 | else
237 | {
238 | var flagInfo = t.GetTypeInfo().GetMember(e.ToString());
239 | bool ignore = flagInfo[0].GetCustomAttribute(typeof(JsonIgnoreAttribute)) != null;
240 | if (ignore)
241 | writer.WriteNull();
242 | else
243 | writer.WriteValue(SerializeValue(e.ToString(), t));
244 | }
245 | }
246 |
247 | private static bool GetIsNullable(Type objectType) => (objectType.GetTypeInfo().IsGenericType && objectType.GetGenericTypeDefinition() == typeof(Nullable<>));
248 |
249 | private object DeserializeValue(string value, Type type)
250 | {
251 | string enumText = value;
252 | // Check EnumMember Values first
253 | string[] flags = type.GetTypeInfo().GetEnumNames();
254 | foreach (string flag in flags)
255 | {
256 | var flagEnum = (Enum)Enum.Parse(type, flag);
257 | var flagInfo = type.GetTypeInfo().GetMember(flag);
258 | var att = (EnumMemberAttribute)flagInfo[0].GetCustomAttribute(typeof(EnumMemberAttribute));
259 | if (att != null && att.Value.Equals(enumText, StringComparison.CurrentCultureIgnoreCase))
260 | return flagEnum;
261 | }
262 |
263 | // Remove SplitWordsWith from value so they can be matched to CamelCase Enum values
264 | if (OutputSplitWords != null)
265 | enumText = enumText.Replace(OutputSplitWords, "");
266 |
267 | return (Enum)Enum.Parse(enumType: type, value: enumText, ignoreCase: true);
268 | }
269 |
270 | private string SerializeValue(string value, Type type)
271 | {
272 | string v = value;
273 | var enumInfo = type.GetTypeInfo().GetMember(v);
274 |
275 | if (enumInfo != null && enumInfo.Length == 1)
276 | {
277 | var att = (EnumMemberAttribute)enumInfo[0].GetCustomAttribute(typeof(EnumMemberAttribute));
278 | if (att != null)
279 | return att.Value;
280 | }
281 |
282 | if (OutputSplitWords != null)
283 | v = v.CamelCaseToRegular(OutputSplitWords);
284 |
285 | switch (OutputCase)
286 | {
287 | case StringCases.Lowercase:
288 | v = v.ToLower();
289 | break;
290 |
291 | case StringCases.Uppercase:
292 | v = v.ToUpper();
293 | break;
294 | }
295 |
296 | return v;
297 | }
298 |
299 | #endregion Methods
300 | }
301 |
302 | public static class StringExtensions
303 | {
304 | ///
305 | /// Converts a string that is in CamelCase to a string array of separate words.
306 | ///
307 | /// The source string to convert.
308 | /// String array to words
309 | ///
310 | /// The following code:
311 | ///
312 | /// "ThisIsInCamelCase".CamelCaseToArray();
313 | ///
314 | /// Result:
315 | /// ["This", "Is", "In", "Camel", "Case"]
316 | ///
317 | ///
318 | internal static string[] CamelCaseToArray(this string source)
319 | {
320 | return Regex.Matches(source, @"(^[a-z\d]+|[A-Z\d]+(?![a-z])|[A-Z][a-z\d]+)")
321 | .OfType()
322 | .Select(m => m.Value)
323 | .ToArray();
324 | }
325 |
326 | ///
327 | /// Converts a string that is in CamelCase to a regular string.
328 | ///
329 | /// The source string to convert.
330 | /// The separator to use between words.
331 | ///
332 | /// The following code:
333 | ///
334 | /// "ThisIsInCamelCase".CamelCaseToRegular();
335 | ///
336 | /// Result:
337 | /// "This Is In Camel Case"
338 | ///
339 | ///
340 | internal static string CamelCaseToRegular(this string source, string separator = " ")
341 | {
342 | string[] s = CamelCaseToArray(source);
343 | return string.Join(separator, s);
344 | }
345 | }
346 | }
--------------------------------------------------------------------------------
/tests/Resources/Encoding/ANSI Cyrillic.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salaros/config-parser/3ed0da9ae156228154d816f12c85c8f7684c7c65/tests/Resources/Encoding/ANSI Cyrillic.txt
--------------------------------------------------------------------------------
/tests/Resources/Encoding/ANSI Latin1.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salaros/config-parser/3ed0da9ae156228154d816f12c85c8f7684c7c65/tests/Resources/Encoding/ANSI Latin1.txt
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF16-BE.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salaros/config-parser/3ed0da9ae156228154d816f12c85c8f7684c7c65/tests/Resources/Encoding/UTF16-BE.txt
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF16-BE.txt.json:
--------------------------------------------------------------------------------
1 | {
2 | "Culture":"",
3 | "Encoding":{
4 | "CodePage":1201
5 | },
6 | "NewLine":"\n"
7 | }
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF16-LE.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salaros/config-parser/3ed0da9ae156228154d816f12c85c8f7684c7c65/tests/Resources/Encoding/UTF16-LE.txt
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF16-LE.txt.json:
--------------------------------------------------------------------------------
1 | {
2 | "Culture":"",
3 | "Encoding":{
4 | "CodePage":1200
5 | },
6 | "NewLine":"\n"
7 | }
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF32-BE.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/salaros/config-parser/3ed0da9ae156228154d816f12c85c8f7684c7c65/tests/Resources/Encoding/UTF32-BE.txt
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF32-BE.txt.json:
--------------------------------------------------------------------------------
1 | {
2 | "Culture":"",
3 | "Encoding":{
4 | "CodePage":12001
5 | },
6 | "NewLine":"\n"
7 | }
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF7.txt:
--------------------------------------------------------------------------------
1 | +AFs-LoremIpsum+AF0-
2 | +1VytbcW0- +AD0- +rW27/Ky9yBzHWA- +vBzIBMdE- +xwTVXA- +yRHGlMgVzEXHWA- +whi5vcXQ- +rQDVWMXs- +swDRtbg5x1g- +x5C7OMXQ- +x1HVWK4w- +xwTVWMXs- +rW27/Ky9yBzHkLs41ozHWLl8- +tFg- +whg- +x4iy5A-.
3 | +A5UDuwO7A7cDvQO5A7oDrA- +AD0- +A7UDrwO9A7EDuQ- +A7EDwAO7A6w- +A60DvQOx- +A7oDtQOvA7wDtQO9A78- +A8cDyQPBA68Dwg- +A70DzAO3A7wDsQ- +A7MDuQOx- +A8QDvwPFA8I- +A7UDwAOxA7MDswO1A7sDvAOxA8QDrwO1A8I- +A8QDtwPC- +A8QDxQPAA78DswPBA7EDxgOvA7EDwg- +A7oDsQO5- +A8MDxAO/A7kDxwO1A7kDvwO4A7UDwwOvA7EDwg-
4 | +Ti1lhw- +AD0- +Tl958E5xZXBQR2WHYhaABVTRUUNlh2cs/ww- +Zi9TcFI3U8pjknJImIZX32JAXjh1KHaEhlpi32WHW1cwAg-
5 | +ZeVnLIqe- +AD0- +ZcUw7U6sl1JSKTC7MOAw7F8xZTkw1TDoMLls4l6cMEswcDB8YQ+QATBnMHyKv2OyW98wXzC5ZeWJf5HNMLEwojDKT09qSzDmMOAw3zCvmAZfhTB1MEswkzB8TrpZaIyvk+EwWTBzMF0wAg-
6 | +CTkJPwkCCSYJQA- +AD0- +CRsJKgk+CQg- +CRQJMA- +CQUJFQlNCTcJMA- +CS8JSwkcCSgJPg- +CQkJJglNCS8JSwkX- +CRUJPg- +CQ8JFQ- +CTgJPgknCT4JMAkj- +CSEJLglA- +CSoJPgkg- +CTkJSA-
7 | +BdAF4AXSBdwF2QXq- +AD0- +BdYF1QXUBdk- +BeIF1QXRBdMF1A- +Bd4F0QXVBeEF4QXq- +BekF0wXiBeoF1Q- +BekF3A- +BdQF5wXVBegF0A- +BeoF1AXZBdQ- +Bd4F1QXhBdcF6g- +BeIF3A- +BdkF0wXZ- +BdgF5wXYBeE- +BecF6AXZBdA- +BdsF0AXpBeg- +BdQF1QXQ- +BdkF0QXZBdg- +BdEF5AXoBdkF4QXqBdU-
8 | +BCAEQwRBBEEEOgQ4BDk- +AD0- Lorem ipsum +IBM- +BD8EQQQ1BDIENAQ+--+BDsEMARCBDgEPQRBBDoEOAQ5- +BEIENQQ6BEEEQg-, +BDoEPgRCBD4EQARLBDk- +BDgEQQQ/BD4EOwRMBDcEQwQ1BEIEQQRP- +BDQEOwRP- +BDIENQQx- +BDQEOAQ3BDAEOQQ9BDA-, +BEIEOAQ/BD4EMwRABDAERAQ4BDg-
9 |
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF7.txt.json:
--------------------------------------------------------------------------------
1 | {
2 | "Culture":"",
3 | "Encoding":{
4 | "CodePage":65000
5 | },
6 | "NewLine":"\n"
7 | }
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF8-Without-BOM.txt:
--------------------------------------------------------------------------------
1 | [LoremIpsum]
2 | 한국어 = 국민경제의 발전을 위한 중요정책의 수립에 관하여 대통령의 자문에 응하기 위하여 국민경제자문회의를 둘 수 있다.
3 | Ελληνικά = είναι απλά ένα κείμενο χωρίς νόημα για τους επαγγελματίες της τυπογραφίας και στοιχειοθεσίας
4 | 中文 = 也称乱数假文或者哑元文本, 是印刷及排版领域所常用的虚拟文字。
5 | 日本語 = 旅ロ京青利セムレ弱改フヨス波府かばぼ意送でぼ調掲察たス日西重ケアナ住橋ユムミク順待ふかんぼ人奨貯鏡すびそ。
6 | हिंदी = छपाई और अक्षर योजना उद्योग का एक साधारण डमी पाठ है
7 | אנגלית = זוהי עובדה מבוססת שדעתו של הקורא תהיה מוסחת על ידי טקטס קריא כאשר הוא יביט בפריסתו
8 | Русский = Lorem ipsum – псевдо-латинский текст, который используется для веб дизайна, типографии
9 |
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF8-Without-BOM.txt.json:
--------------------------------------------------------------------------------
1 | {
2 | "Culture":"",
3 | "Encoding":{
4 | "CodePage":65001,
5 | "WithPreamble":false
6 | },
7 | "NewLine":"\n"
8 | }
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF8.txt:
--------------------------------------------------------------------------------
1 | [LoremIpsum]
2 | 한국어 = 국민경제의 발전을 위한 중요정책의 수립에 관하여 대통령의 자문에 응하기 위하여 국민경제자문회의를 둘 수 있다.
3 | Ελληνικά = είναι απλά ένα κείμενο χωρίς νόημα για τους επαγγελματίες της τυπογραφίας και στοιχειοθεσίας
4 | 中文 = 也称乱数假文或者哑元文本, 是印刷及排版领域所常用的虚拟文字。
5 | 日本語 = 旅ロ京青利セムレ弱改フヨス波府かばぼ意送でぼ調掲察たス日西重ケアナ住橋ユムミク順待ふかんぼ人奨貯鏡すびそ。
6 | हिंदी = छपाई और अक्षर योजना उद्योग का एक साधारण डमी पाठ है
7 | אנגלית = זוהי עובדה מבוססת שדעתו של הקורא תהיה מוסחת על ידי טקטס קריא כאשר הוא יביט בפריסתו
8 | Русский = Lorem ipsum – псевдо-латинский текст, который используется для веб дизайна, типографии
9 |
--------------------------------------------------------------------------------
/tests/Resources/Encoding/UTF8.txt.json:
--------------------------------------------------------------------------------
1 | {
2 | "Culture":"",
3 | "Encoding":{
4 | "CodePage":65001
5 | },
6 | "NewLine":"\n"
7 | }
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/CONFIG.SYS:
--------------------------------------------------------------------------------
1 | DOS=HIGH,UMB
2 | DEVICE=C:\DOS\HIMEM.SYS
3 | DEVICE=C:\DOS\EMM386.EXE RAM
4 | DEVICEHIGH=C:\DOS\ANSI.SYS
5 | FILES=30
6 | SHELL=C:\DOS\COMMAND.COM C:\DOS /E:512 /P
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/CONFIG.SYS.json:
--------------------------------------------------------------------------------
1 | {
2 | "MultiLineValues": [
3 | "AllowEmptyTopSection"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/FALLOUT.INI:
--------------------------------------------------------------------------------
1 | [General]
2 | SStartingCell=
3 | SCharGenQuest=0001f388
4 | SStartingCellY=
5 | SStartingCellX=
6 | SStartingWorld=
7 |
8 | STestFile10=
9 | STestFile9=
10 | STestFile8=
11 | STestFile7=
12 | STestFile6=
13 | STestFile5=
14 | STestFile4=
15 | STestFile3=
16 | STestFile2=
17 | STestFile1=Fallout3.esm
18 |
19 | sEssentialFileCacheList=Data\Fallout.esm|Data2\Fallout.esm, Data\Music\Special\MainTitle.mp3, Data\Fallout - Sound.bsa|Fallout - Sound.bsa, Data\Fallout - Voices.bsa|Fallout - Voices.bsa, Data\Fallout - MenuVoices.bsa|Fallout - MenuVoices.bsa
20 | sUnessentialFileCacheList=Data\Fallout - Meshes.bsa|Data2\Fallout - Meshes.bsa, Data\Fallout - Textures.bsa|Data2\Fallout - Textures.bsa, Data\Music\Dungeon\*.xma, Data\Music\Base\*.mp3, Data\Music\Battle\*.mp3, Data\Music\Explore\*.mp3, Data\Music\Public\*.mp3, Data\Music\Special\*.mp3
21 | bPreCullActors=1
22 | bTaskletActorSceneGraphUpdates=0
23 | bTaskletActorAnimMovementUpdates=1
24 | bAnimationUseBlendFromPose=1
25 | bEnableProfile=0
26 | bDrawSpellContact=0
27 | bRunMiddleLowLevelProcess=1
28 | iHoursToSleep=3
29 | bActorLookWithHavok=0
30 | SMainMenuMusicTrack=special\maintitle.mp3
31 | bUseEyeEnvMapping=1
32 | bFixFaceNormals=0
33 | bUseFaceGenHeads=1
34 | bFaceMipMaps=1
35 | bFaceGenTexturing=1
36 | SBetaCommentFileName=\\vault\Fallout\Fallout3\Beta_Comment.txt
37 | bDefaultCOCPlacement=0
38 | uGridDistantCount=20
39 | uGridsToLoad=5
40 | fGlobalTimeMultiplier=1.0000
41 | bNewAnimation=1
42 | bFixAIPackagesOnLoad=0
43 | bForceReloadOnEssentialCharacterDeath=1
44 | bKeepPluginWhenMerging=0
45 | bCreate Maps Enable=0
46 | SLocalSavePath=Saves\
47 | SLocalMasterPath=Data\
48 | bDisableDuplicateReferenceCheck=1
49 | bTintMipMaps=0
50 | uInterior Cell Buffer=3
51 | uExterior Cell Buffer=36
52 | iIntroSequencePriority=3
53 | bPreloadIntroSequence=1
54 | fStaticScreenWaitTime=3.0000
55 | SMainMenuMovieIntro=
56 | SIntroSequence=
57 | sIntroMovie=Fallout INTRO Vsk.bik
58 | iFPSClamp=0
59 | bRunVTuneTest=0
60 | STestFile1=
61 | bActivateAllQuestScripts=0
62 | bUseThreadedBlood=1
63 | bUseThreadedMorpher=1
64 | bBorderRegionsEnabled=1
65 | bDisableHeadTracking=0
66 | bTrackAllDeaths=0
67 | uiFaceGenMaxEGTDataSize=67108864
68 | uiFaceGenMaxEGMDataSize=67108864
69 | bPreemptivelyUnloadCells=0
70 | iNumBitsForFullySeen=248
71 | iPreloadSizeLimit=26214400
72 | bUseHardDriveCache=0
73 | bEnableBoundingVolumeOcclusion=1
74 | bDisplayBoundingVolumes=0
75 | bUseThreadedTempEffects=1
76 | bUseThreadedParticleSystem=1
77 | bExternalLODDataFiles=1
78 | bCheckCellOffsetsOnInit=0
79 | uGridDistantTreeRange=5
80 | bCreateShaderPackage=0
81 | bWarnOnMissingFileEntry=0
82 | bAllowScriptedAutosave=0
83 | uGridDistantTreeRangeCity=4
84 | uGridDistantCountCity=4
85 | iSaveGameBackupCount=1
86 | bDisplayMissingContentDialogue=1
87 | SSaveGameSafeCellID=2AEEA
88 | bUseThreadedAI=1
89 | INumHWThreads=4
90 | bChangeTimeMultSlowly=1
91 | bCheckPurgedTextureList=0
92 | bAnimateDoorPhysics=0
93 | sLanguage=ENGLISH
94 |
95 | [Display]
96 | fDecalLifetime=10.0000
97 | bEquippedTorchesCastShadows=0
98 | bReportBadTangentSpace=0
99 | bStaticMenuBackground=1
100 | bForcePow2Textures=0
101 | bForce1XShaders=0
102 | bHighQuality20Lighting=0
103 | bAllow20HairShader=1
104 | bAllowScreenShot=1
105 | iMultiSample=0
106 | bDoTallGrassEffect=1
107 | bForceMultiPass=1
108 | bDoTexturePass=1
109 | bDoSpecularPass=1
110 | bDoDiffusePass=1
111 | bDoAmbientPass=1
112 | bImageSpaceEffects=1
113 | bDoCanopyShadowPass=1
114 | bDrawShadows=0
115 | bUseRefractionShader=1
116 | bUse Shaders=1
117 | iNPatchNOrder=0
118 | iNPatchPOrder=0
119 | iNPatches=0
120 | iLocation Y=5
121 | iLocation X=5
122 | bFull Screen=1
123 | iAdapter=0
124 | iScreenShotIndex=0
125 | SScreenShotBaseName=ScreenShot
126 | iAutoViewMinDistance=2000
127 | iAutoViewHiFrameRate=40
128 | iAutoViewLowFrameRate=20
129 | bAutoViewDistance=0
130 | fDefaultFOV=95.0000
131 | fNearDistance=5
132 | fFarDistance=1000.0000
133 | iDebugTextLeftRightOffset=10
134 | iDebugTextTopBottomOffset=20
135 | bShowMenuTextureUse=1
136 | fLightLODDefaultStartFade=1000.0
137 | fLightLODRange=500.0
138 | fLightLODMinStartFade=200.0
139 | fLightLODMaxStartFade=3500.0
140 | fShadowLODDefaultStartFade=200.0
141 | fShadowLODRange=200.0
142 | fShadowLODMinStartFade=100.0
143 | fShadowLODMaxStartFade=1000.0
144 | fSpecularLODDefaultStartFade=500.0
145 | fSpecularLODRange=300.0
146 | fSpecularLODMinStartFade=200.0
147 | fSpecularLODMaxStartFade=2000.0
148 | fGamma=1.0000
149 | bAllow30Shaders=0
150 | iTexMipMapMinimum=0
151 | bDoStaticAndArchShadows=0
152 | bDoActorShadows=1
153 | fNoLODFarDistancePct=1.0000
154 | fNoLODFarDistanceMax=10240.0000
155 | fNoLODFarDistanceMin=100.0000
156 | fEyeEnvMapLOD2=800.0000
157 | fEyeEnvMapLOD1=500.0000
158 | fEnvMapLOD2=1800.0000
159 | fEnvMapLOD1=1500.0000
160 | fGammaMax=0.6000
161 | fGammaMin=1.4000
162 | iMaxDecalsPerFrame=10
163 | iActorShadowCount=4
164 | bIgnoreResolutionCheck=0
165 | fSpecualrStartMax=1000.0000
166 | fSpecularStartMin=0.0000
167 | iActorShadowIntMax=10
168 | iActorShadowIntMin=0
169 | iActorShadowExtMax=10
170 | iActorShadowExtMin=0
171 | bDynamicWindowReflections=1
172 | fShadowFadeTime=1.0000
173 | iPresentInterval=0
174 | bDecalsOnSkinnedGeometry=1
175 | uVideoDeviceIdentifierPart4=0
176 | uVideoDeviceIdentifierPart3=0
177 | uVideoDeviceIdentifierPart2=0
178 | uVideoDeviceIdentifierPart1=0
179 | iShadowFilter=0
180 | bAllowPartialPrecision=1
181 | iShadowMapResolution=256
182 | bShadowsOnGrass=0
183 | bActorSelfShadowing=0
184 | iActorShadowCountInt=2
185 | iActorShadowCountExt=2
186 | fPipboy1stPersonFOV=47.0
187 | fDefault1stPersonFOV=55.0000
188 | bLODNoiseAniso=1
189 | iMaxAnisotropy=8
190 | fLandLOFadeSeconds=15.0
191 |
192 | [Controls]
193 | bAlwaysRunByDefault=1
194 | bBackground Mouse=0
195 | bBackground Keyboard=1
196 | fForegroundMouseAccelBase=0
197 | fForegroundMouseAccelTop=0
198 | fForegroundMouseBase=0
199 | fForegroundMouseMult=0
200 |
201 | [Water]
202 | bUseWaterShader=0
203 | bUseWaterReflections=0
204 | bUseWaterRefractions=0
205 | bUseWaterDepth=1
206 | bUseWaterHiRes=0
207 | bUseWaterDisplacements=1
208 | bUseWaterLOD=1
209 | bReflectExplosions=0
210 | bAutoWaterSilhouetteReflections=0
211 | bForceHighDetailReflections=0
212 | bForceLowDetailReflections=0
213 | fTileTextureDivisor=4.7500
214 | fSurfaceTileSize=2048.0000
215 | fNearWaterOutdoorTolerance=1024.0000
216 | fNearWaterIndoorTolerance=512.0000
217 | fNearWaterUnderwaterVolume=0.9000
218 | fNearWaterUnderwaterFreq=0.3000
219 | uNearWaterPoints=8
220 | uNearWaterRadius=1000
221 | uSurfaceFPS=12
222 |
223 | [Audio]
224 | fASFadeInTime=3.0
225 | fASFadeOutTime=10.0
226 | fRegionLoopFadeInTime=5.0
227 | fRegionLoopFadeOutTime=5.0
228 | fAudioDebugDelay=0.0
229 | bEnableAudio=1
230 | bEnableAudioCache=1
231 | bMultiThreadAudio=1
232 | bEnableEnviroEffectsOnPC=0
233 | ; cache sizes in kilobytes
234 | iAudioCacheSize=2048
235 | iMaxSizeForCachedSound=256
236 | bUseAudioDebugInformation=1
237 | fAudioDebugDelay=0.0000
238 | fDefaultMasterVolume=1.0000
239 | fDefaultFootVolume=0.5000
240 | fDefaultMusicVolume=0.3000
241 | fDefaultRadioVolume=0.5000
242 | fDefaultEffectsVolume=1.0000
243 | fDefaultVoiceVolume=0.7500
244 | iMaxImpactSoundCount=32
245 | fMaxFootstepDistance=1100.0000
246 | fPlayerFootVolume=0.6500
247 | iCollisionSoundTimeDelta=150
248 | iRadioUpdateInterval=250
249 | fMinSoundVel=90.0000
250 | fDialogMinDistance=125.00
251 | fDialogMaxDistance=1800.00
252 | fMainMenuMusicVolume=0.6
253 | fDBVoiceAttenuationIn2D=2.0
254 | fCollisionSoundHeavyThreshold=60.0
255 | fDialogueFadeDecibels=6.0
256 | fDialogueFadeSecondsIn=2.0
257 | fDialogueFadeSecondsOut=1.0
258 | fDialogueHeadPitchExaggeration=2.0
259 | fDialogueHeadRollExaggeration=2.0
260 | fDialogueHeadYawExaggeration=2.0
261 | fHardLandingDamageThreshold=500.0
262 | fWoodMediumMassMin=7.0
263 | fWoodLargeMassMin=15.0
264 | fStoneMediumMassMin=5.0
265 | fStoneLargeMassMin=30.0
266 | fEarthMediumMassMin=5.0
267 | fEarthLargeMassMin=30.0
268 | fSkinMediumMassMin=5.0
269 | fSkinLargeMassMin=30.0
270 | fMetalMediumMassMin=8.0
271 | fMetalLargeMassMin=25.0
272 | fRadioDialogMute=0.50
273 | fFilterDistortionGain=-7.5
274 | fFilterPEQGain=-15.0
275 | fFilterdBAttenuation=11.5
276 |
277 | [Pathfinding]
278 | bDrawPathsDefault=0
279 | bPathMovementOnly=0
280 | bDrawSmoothFailures=0
281 | bDebugSmoothing=0
282 | bSmoothPaths=1
283 | bSnapToAngle=0
284 | bDebugAvoidance=0
285 | bDisableAvoidance=0
286 | bBackgroundPathing=1
287 | bUseObstacleAvoidance=1
288 | bBackgroundNavmeshUpdate=1
289 |
290 | [MAIN]
291 | bEnableBorderRegion=1
292 | fLowPerfCombatantVoiceDistance=1000.0000
293 | iDetectionHighNumPicks=40
294 | fQuestScriptDelayTime=5.0000
295 | bCloneModelsInBackground=0
296 | iLastHDRSetting=-1
297 |
298 | [HAVOK]
299 | bDisablePlayerCollision=0
300 | fJumpAnimDelay=0.7500
301 | bTreeTops=0
302 | iSimType=1
303 | bPreventHavokAddAll=0
304 | bPreventHavokAddClutter=0
305 | fMaxTime=0.016
306 | bHavokDebug=0
307 | fRF=1000.0000
308 | fOD=0.9000
309 | fSE=0.3000
310 | fSD=0.9800
311 | iResetCounter=5
312 | fMoveLimitMass=95.0000
313 | iUpdateType=0
314 | bHavokPick=0
315 | fCameraCasterSize=10.0000
316 | iHavokSkipFrameCountTEST=0
317 | iNumHavokThreads=1
318 | fChaseDeltaMult=0.0500
319 | bAddBipedWhenKeyframed=1
320 | fQuadrupedPitchMult=1.0000
321 | iEntityBatchRemoveRate=100
322 | iMaxPicks=40
323 |
324 | [RagdollAnim]
325 | bRagdollFeedback=1
326 | fCameraDist=1000.0
327 | fHierarchyGain=0.17
328 | fVelocityDamping=0.0
329 | fAccelerationGain=1.0
330 | fVelocityGain=0.6
331 | fPositionGain=0.05
332 | fPositionMaxLinearVelocity=14.0
333 | fPositionMaxAngularVelocity=18.0
334 | fSnapGain=0.1
335 | fSnapMaxLinearVelocity=3.0
336 | fSnapMaxAngularVelocity=0.3
337 | fSnapMaxLinearDistance=0.3
338 | fSnapMaxAngularDistance=1.0
339 |
340 | [FootIK]
341 | fOnOffGain=0.5
342 | fGroundAscendingGain=0.4
343 | fGroundDescendingGain=0.4
344 | fFootRaisedGain=0.9000
345 | fFootPlantedGain=1.0000
346 | bFootPlacementOn=1
347 | fPelvisUpDownBias=0.75
348 | fPelvisOffsetDamping=0.2
349 | fVertErrorGain=0.5
350 | fOriginalGroundHeightMS=-0.11
351 | fAnkleOffset=0.2000
352 | fRagdollFeedback=0.7
353 |
354 | [LookIK]
355 | fLookAtTargetGain=0.3
356 | fLookAtGain=0.045
357 |
358 | [Interface]
359 | fKeyRepeatInterval=50.0000
360 | fKeyRepeatTime=500.0000
361 | fActivatePickSphereRadius=16.0000
362 | fMenuModeAnimBlend=0.0000
363 | iSafeZoneXWide=15
364 | iSafeZoneYWide=15
365 | iSafeZoneX=15
366 | iSafeZoneY=15
367 | bAllowConsole=1
368 | bActivatePickUseGamebryoPick=0
369 | bUseFuzzyPicking=1
370 | fMenuBGBlurRadius=2.0000
371 | fMenuPlayerLightDiffuseBlue=0.8000
372 | fMenuPlayerLightDiffuseGreen=0.8000
373 | fMenuPlayerLightDiffuseRed=0.8000
374 | fMenuPlayerLightAmbientBlue=0.2500
375 | fMenuPlayerLightAmbientGreen=0.2500
376 | fMenuPlayerLightAmbientRed=0.2500
377 | iMaxViewCasterPicksGamebryo=10
378 | iMaxViewCasterPicksHavok=10
379 | iMaxViewCasterPicksFuzzy=5
380 | fInterfaceTintB=0.8824
381 | fInterfaceTintG=0.9843
382 | fInterfaceTintR=0.6314
383 | bUseImageSpaceMenuFX=0
384 |
385 | iSystemColorTerminalRed=33
386 | iSystemColorTerminalGreen=231
387 | iSystemColorTerminalBlue=121
388 |
389 | iSystemColorSystemRed=26
390 | iSystemColorSystemGreen=255
391 | iSystemColorSystemBlue=128
392 |
393 | iSystemColorMainMenuRed=199
394 | iSystemColorMainMenuGreen=255
395 | iSystemColorMainMenuBlue=165
396 |
397 | iSystemColorPipboyRed=26
398 | iSystemColorPipboyGreen=255
399 | iSystemColorPipboyBlue=128
400 |
401 | iSystemColorHUDAltRed=255
402 | iSystemColorHUDAltGreen=67
403 | iSystemColorHUDAltBlue=42
404 |
405 | iSystemColorHUDMainRed=26
406 | iSystemColorHUDMainGreen=255
407 | iSystemColorHUDMainBlue=128
408 |
409 | fRSMFaceSliderDefaultMin=-3.5
410 | fRSMFaceSliderDefaultMax=3.5
411 |
412 | fPopUpBackgroundOpacity=0.87
413 | fMenuBackgroundOpacity=0.76
414 | bHideUnavailablePerks=0
415 |
416 |
417 | [Loading]
418 | sWelcomeScreen1=loading_screen01
419 | sWelcomeScreen2=loading_screen_bethsoft
420 | sWelcomeScreen3=loading_screen_BGS
421 | sWelcomeScreen4=loading_screen_legal
422 | sMainMenuBackground=main_background
423 | sTitleMusic=MainTitle
424 | sInitialSound=fx\ui\loadscreen\initial\ui_loadscreen_initial.wav
425 | iMaxScreens=4
426 | iMaxScreens_MainMenu=20
427 | fLoadingTextUpdateInterval=10.0000
428 | fLoadingBkgdUpdateInterval=10.0000
429 | fMainMenuBkgdUpdateInterval=10.0000
430 | fLoadingInitUpdateInterval=5.0000
431 | iNumLocationSpecificScreens=1
432 |
433 |
434 | [Menu]
435 | fCreditsScrollSpeed=40.0000
436 | iConsoleTextYPos=940
437 | iConsoleTextXPos=30
438 | iConsoleVisibleLines=23
439 | iConsoleHistorySize=9001
440 | rDebugTextColor=255,251,233
441 | iConsoleFont=2
442 | iDebugTextFont=3
443 |
444 | [GamePlay]
445 | bHealthBarShowing=0
446 | fHealthBarFadeOutSpeed=1.0000
447 | fHealthBarSpeed=80.0000
448 | fHealthBarHeight=4.0000
449 | fHealthBarWidth=40.0000
450 | fHealthBarEmittanceFadeTime=0.5000
451 | fHealthBarEmittanceTime=1.5000
452 | bAllowHavokGrabTheLiving=0
453 | bEssentialTakeNoDamage=1
454 | iDetectionPicks=21
455 |
456 | [Fonts]
457 | sFontFile_1=Textures\Fonts\Glow_Monofonto_Large.fnt
458 | sFontFile_2=Textures\Fonts\Monofonto_Large.fnt
459 | sFontFile_3=Textures\Fonts\Glow_Monofonto_Medium.fnt
460 | sFontFile_4=Textures\Fonts\Monofonto_VeryLarge02_Dialogs2.fnt
461 | sFontFile_5=Textures\Fonts\Fixedsys_Comp_uniform_width.fnt
462 | sFontFile_6=Textures\Fonts\Glow_Monofonto_VL_dialogs.fnt
463 | sFontFile_7=Textures\Fonts\Baked-in_Monofonto_Large.fnt
464 | sFontFile_8=Textures\Fonts\Glow_Futura_Caps_Large.fnt
465 |
466 | [SpeedTree]
467 | iTreeClonesAllowed=1
468 | fCanopyShadowGrassMult=1.0000
469 | iCanopyShadowScale=512
470 | fTreeForceMaxBudAngle=-1.0000
471 | fTreeForceMinBudAngle=-1.0000
472 | fTreeForceLeafDimming=-1.0000
473 | fTreeForceBranchDimming=-1.0000
474 | fTreeForceCS=-1.0000
475 | fTreeForceLLA=-1.0000
476 | fTreeLODExponent=1.0000
477 | bEnableTrees=1
478 | bForceFullLOD=0
479 | fLODTreeMipMapLODBias=-0.7500
480 | fLocalTreeMipMapLODBias=-0.2500
481 |
482 | [Debug]
483 | bDebugFaceGenCriticalSection=0
484 | bDebugFaceGenMultithreading=0
485 | bDebugSaveBuffer=0
486 |
487 | [BackgroundLoad]
488 | bBackgroundPathing=1
489 | bUseMultiThreadedFaceGen=1
490 | bBackgroundCellLoads=1
491 | iAnimaitonClonePerLoop=5
492 | bUseMultiThreadedTrees=1
493 | iExteriorPriority=50
494 | iBackgroundLoadFaceMult=200
495 | fBackgroundLoadingPerLoop=20.0000
496 | fBackgroundLoadClonedPerLoop=5.0000
497 | iBackgroundLoadExtraMaxFPS=20
498 | iBackgroundLoadExtraMinFPS=10
499 | iBackgroundLoadExtraMax=3000
500 | iBackgroundLoadExtraMin=5
501 | iBackgroundLoadExtraMilliseconds=2
502 | iBackgroundLoadTreeMilliseconds=7
503 | iBackgroundLoadMilliseconds=1
504 | iBackgroundLoadLoading=1
505 | bUseBackgroundFileLoader=0
506 | bBackgroundLoadLipFiles=0
507 | bLoadBackgroundFaceGen=0
508 | bLoadHelmetsInBackground=1
509 | iAnimationClonePerLoop=5
510 | bSelectivePurgeUnusedOnFastTravel=0
511 | bCloneModelsInBackground=0
512 |
513 | [LOD]
514 | fLODLandDropAmount=230.0000
515 | fLodDistance=500.0000
516 | bUseFaceGenLOD=0
517 | iLODTextureTiling=2
518 | iLODTextureSizePow2=8
519 | fLODNormalTextureBlend=0.5000
520 | bDisplayLODLand=1
521 | bDisplayLODBuildings=0
522 | bLODPopTrees=0
523 | bLODPopActors=0
524 | bLODPopItems=0
525 | bLODPopObjects=0
526 | fLODFadeOutMultItems=3
527 | fLODFadeOutMultObjects=5
528 | fLODFadeOutMultActors=6
529 | fLODMultLandscape=1.0000
530 | fLODMultTrees=0.5000
531 | fLODMultActors=1.0000
532 | fLODMultItems=1.0000
533 | fLODMultObjects=5
534 | iFadeNodeMinNearDistance=500
535 | fLODFadeOutPercent=0.6000
536 | fFadeOutThreshold=0.3000
537 | fFadeInThreshold=0.7000
538 | fFadeInTimet=2.0
539 | fFadeOutTime=2.0
540 | fDistanceMultiplier=1
541 | fLODBoundRadiusMult=10
542 | fObjectLODMax=15.0
543 | fObjectLODMin=1.0
544 | fObjectLODDefault=5
545 | fItemLODMax=15.0
546 | fItemLODMin=1.0
547 | fItemLODDefault=2
548 | fActorLODMax=15.0
549 | fActorLODMin=2.0
550 | fActorLODDefault=5
551 | fTreeLODMax=2.0000
552 | fTreeLODMin=0.0200
553 | fTreeLODDefault=0.5000
554 | bLODUseCombinedLandNormalMaps=1
555 | bForceHideLODLand=0
556 | fLODLandVerticalBias=0.0000
557 | fTalkingDistance=1000.0000
558 | iBoneLODForce=-1
559 | fLODQuadMinLoadDistance=65536.0000
560 | bDisplayLODTrees=1
561 | bDisplayLODBuildings=1
562 | fLODFadeOutActorMultInterior=1.0000
563 | fLODFadeOutItemMultInterior=1.0000
564 | fLODFadeOutObjectMultInterior=1.0000
565 | fLODFadeOutActorMultCity=1.0000
566 | fLODFadeOutItemMultCity=1.0000
567 | fLODFadeOutObjectMultCity=1.0000
568 | fLODFadeOutActorMultComplex=1.0000
569 | fLODFadeOutItemMultComplex=1.0000
570 | fLODFadeOutObjectMultComplex=1.0000
571 |
572 | [Weather]
573 | fSunGlareSize=800.0000
574 | fSunBaseSize=750.0000
575 | bPrecipitation=1
576 | fAlphaReduce=1.0000
577 | SBumpFadeColor=255,255,255,255
578 | SLerpCloseColor=255,255,255,255
579 | SEnvReduceColor=255,255,255,255
580 |
581 | [Voice]
582 | SFileTypeLTF=ltf
583 | SFileTypeLip=lip
584 | SFileTypeSource=wav
585 | SFileTypeGame=ogg
586 |
587 | [Grass]
588 | iMinGrassSize=80
589 | bGrassPointLighting=0
590 | bDrawShaderGrass=1
591 | iGrassDensityEvalSize=2
592 | iMaxGrassTypesPerTexure=2
593 | fWaveOffsetRange=1.7500
594 | fGrassWindMagnitudeMax=125.0000
595 | fGrassWindMagnitudeMin=5.0000
596 | fTexturePctThreshold=0.0000
597 | fGrassMinStartFadeDistance=0.0
598 | fGrassMaxStartFadeDistance=7000.0
599 | fGrassDefaultStartFadeDistance=3500.0
600 | fGrassFadeRange=1000.0
601 |
602 | [Landscape]
603 | bCurrentCellOnly=0
604 | bPreventSafetyCheck=0
605 | fLandTextureTilingMult=2.0000
606 | fLandFriction=2.5000
607 | iLandBorder2B=0
608 | iLandBorder2G=0
609 | iLandBorder2R=0
610 | iLandBorder1B=0
611 | iLandBorder1G=255
612 | iLandBorder1R=255
613 | SDefaultLandDiffuseTexture=DirtWasteland01.dds
614 | SDefaultLandNormalTexture=DirtWasteland01_N.dds
615 |
616 | [bLightAttenuation]
617 | fQuadraticRadiusMult=1.0000
618 | fLinearRadiusMult=1.0000
619 | bOutQuadInLin=0
620 | fConstantValue=0.0000
621 | fQuadraticValue=16.0000
622 | fLinearValue=3.0000
623 | uQuadraticMethod=2
624 | uLinearMethod=1
625 | fFlickerMovement=8.0000
626 | bUseQuadratic=1
627 | bUseLinear=0
628 | bUseConstant=0
629 |
630 | [BlurShaderHDRInterior]
631 | fTargetLUM=1.0000
632 | fUpperLUMClamp=1.0000
633 | fEmissiveHDRMult=1.0000
634 | fEyeAdaptSpeed=0.5000
635 | fBrightScale=2.2500
636 | fBrightClamp=0.2250
637 | fBlurRadius=7.0000
638 | iNumBlurpasses=1
639 |
640 | [BlurShaderHDR]
641 | fTargetLUM=1.0000
642 | fUpperLUMClamp=1.0000
643 | fGrassDimmer=1.5000
644 | fTreeDimmer=1.0000
645 | fEmissiveHDRMult=1.0000
646 | fEyeAdaptSpeed=0.5000
647 | fSunlightDimmer=1.5000
648 | fSIEmmisiveMult=1.0000
649 | fSISpecularMult=1.0000
650 | fSkyBrightness=0.5000
651 | fSunBrightness=0.0000
652 | fBrightScale=2.2500
653 | fBrightClamp=0.2250
654 | fBlurRadius=7.0000
655 | iNumBlurpasses=1
656 | iBlendType=2
657 | bDoHighDynamicRange=1
658 |
659 | [BlurShader]
660 | fSunlightDimmer=1.0000
661 | fSIEmmisiveMult=1.0000
662 | fSISpecularMult=1.0000
663 | fSkyBrightness=0.5000
664 | fSunBrightness=0.0000
665 | fAlphaAddExterior=0.2000
666 | fAlphaAddInterior=0.7000
667 | iBlurTexSize=256
668 | fBlurRadius=0.0300
669 | iNumBlurpasses=1
670 | iBlendType=2
671 | bUseBlurShader=1
672 |
673 | [GethitShader]
674 | fBlurAmmount=0.5000
675 | fBlockedTexOffset=0.0010
676 | fHitTexOffset=0.0050
677 |
678 | [MESSAGES]
679 | bBlockMessageBoxes=0
680 | bSkipProgramFlows=1
681 | bAllowYesToAll=1
682 | bDisableWarning=1
683 | iFileLogging=0
684 | bSkipInitializationFlows=1
685 | bUseWindowsMessageBox=0
686 |
687 | [DistantLOD]
688 | bUseLODLandData=0
689 | fFadeDistance=12288.0000
690 | iDistantLODGroupWidth=8
691 |
692 | [GeneralWarnings]
693 | SGeneralMasterMismatchWarning=One or more plugins could not find the correct versions of the master files they depend on. Errors may occur during load or game play. Check the "Warnings.txt" file for more information.
694 |
695 | SMasterMismatchWarning=One of the files that "%s" is dependent on has changed since the last save.
696 | This may result in errors. Saving again will clear this message
697 | but not necessarily fix any errors.
698 |
699 | [Archive]
700 | SMasterMiscArchiveFileName=Fallout - Misc.bsa
701 | SMasterVoicesArchiveFileName1=Fallout - Voices.bsa
702 | SMasterVoicesArchiveFileName2=Fallout - MenuVoices.bsa
703 | SMasterSoundsArchiveFileName=Fallout - Sound.bsa
704 | SMasterTexturesArchiveFileName1=Fallout - Textures.bsa
705 | SMasterMeshesArchiveFileName=Fallout - Meshes.bsa
706 | SInvalidationFile=ArchiveInvalidation.txt
707 | iRetainFilenameOffsetTable=1
708 | iRetainFilenameStringTable=1
709 | iRetainDirectoryStringTable=1
710 | bCheckRuntimeCollisions=0
711 | bInvalidateOlderFiles=0
712 | bUseArchives=1
713 | SArchiveList=Fallout - Textures.bsa, Fallout - Meshes.bsa, Fallout - Voices.bsa, Fallout - Sound.bsa, Fallout - MenuVoices.bsa, Fallout - Misc.bsa
714 |
715 | [CameraPath]
716 | iTake=0
717 | SDirectoryName=TestCameraPath
718 | iFPS=60
719 | SNif=Test\CameraPath.nif
720 |
721 | [Absorb]
722 | fAbsorbGlowColorB=1.0000
723 | fAbsorbGlowColorG=0.6000
724 | fAbsorbGlowColorR=0.0000
725 | fAbsorbCoreColorB=1.0000
726 | fAbsorbCoreColorG=1.0000
727 | fAbsorbCoreColorR=1.0000
728 | iAbsorbNumBolts=1
729 | fAbsorbBoltGrowWidth=0.0000
730 | fAbsorbBoltSmallWidth=7.0000
731 | fAbsorbTortuosityVariance=2.0000
732 | fAbsorbSegmentVariance=7.0000
733 | fAbsorbBoltsRadius=5.0000
734 |
735 | [TestAllCells]
736 | bFileShowTextures=1
737 | bFileShowIcons=1
738 | bFileSkipIconChecks=0
739 | bFileTestLoad=0
740 | bFileNeededMessage=1
741 | bFileGoneMessage=1
742 | bFileSkipModelChecks=0
743 | bFileCheckModelCollision=0
744 |
745 | [CopyProtectionStrings]
746 | SCopyProtectionMessage2=Insert the Fallout Disc.
747 | SCopyProtectionTitle2=Fallout Disc Not Found
748 | SCopyProtectionMessage=Unable to find a CD-ROM/DVD drive on this computer.
749 | SCopyProtectionTitle=CD-ROM Drive Not Found
750 |
751 | [Pipboy]
752 | fBlurRadiusPipboy=3.5
753 | fBlurIntensityPipboy=0.25
754 | fScanlineScalePipboy=50
755 | bEnableFlickerPipboy=1
756 | bUsePipboyMode=1
757 |
758 | [InterfaceFX]
759 | fDefaultBurstDuration=200
760 | fDefaultBurstIntensity=2
761 | fMiniBurstDuration=200
762 | fMiniBurstIntensity=1.5
763 |
764 | ;pulse effect
765 | fPulseBrightenIntensity=0.25
766 | fPulseRadiusIntensity=0.5
767 | fPulseRate=0.0006
768 |
769 | ;pipboy menu transitions
770 | fVertHoldChance=0.08
771 | fShudderChance=0.20
772 |
773 | fScanlineScaleMenus=50.0000
774 | bEnableFlickerMenus=1
775 | bEnableScanlinesMenus=1
776 | bEnableScanlinesPipboy=1
777 | fBlurRadiusMenus=0.3000
778 | fBrightenMenus=1.7000
779 | fBrightenPipboy=1.3000
780 | bUseImageSpaceMenuFX=1
781 | fBlurIntensityHUD=1.2000
782 | fBlurRadiusHUD=2.0000
783 | fScanlineFrequencyHUD=0.0000
784 |
785 | fScreenLightBaseIntensity=0.6
786 | fScreenLightRadius=6
787 |
788 | [RenderedTerminal]
789 | bUseRenderedTerminals=1
790 | fRenderedTerminalFOV=0.15
791 | fRenderedTerminalZoom=36
792 | bDoRenderedTerminalScanlines=1
793 | fRenderedTerminalScanlineScale=130.000000
794 | fRenderedTerminalHPos=0.0
795 | fRenderedTerminalVPos=0.38
796 | fScreenLightBaseIntensity=1.2
797 | fScreenLightRadius=80
798 | fScreenLightColorR=0.68
799 | fScreenLightColorG=0.74
800 | fScreenLightColorB=0.62
801 |
802 | fRaceSexMenuHPos=0.0
803 | fRaceSexMenuVPos=-0.6
804 | fRaceSexMenuZoom=70.0
805 | fRaceSexMenuScale=0.5
806 |
807 | [Decals]
808 | uMaxDecalCount=100
809 | bProfileDecals=0
810 | bDecalOcclusionQuery=1
811 |
812 | [TerrainManager]
813 | fSplitDistanceMult=0.75
814 | fBlockMorphDistanceMult=0.70
815 | bUseNewTerrainSystem=1
816 | bUseDistantObjectBlocks=1
817 | fBlockLoadDistance=125000.0
818 | fDefaultBlockLoadDistanceLow=50000.0
819 | fLowBlockLoadDistanceLow=25000.0
820 | fHighBlockLoadDistanceLow=50000.0
821 | fDefaultTreeLoadDistance=25000.0
822 | fLowTreeLoadDistance=10000.0
823 | fHighTreeLoadDistance=40000.0
824 |
825 | [VATS]
826 | fVATSLightLevelMin=20.0
827 | fVATSLightLevelMax=65.0
828 | fVATSLightAngle=0.0
829 | fVATSLightDistance=100.0
830 | fVATSLightElevation=100.0
831 | fVatsLightColorR=0.35
832 | fVatsLightColorG=0.35
833 | fVatsLightColorB=0.35
834 |
835 | [ScreenSplatter]
836 | bScreenSplatterEnabled=1
837 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/FALLOUT.INI.json:
--------------------------------------------------------------------------------
1 | {
2 | "MultiLineValues": [
3 | "Simple"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/Gothic.INI:
--------------------------------------------------------------------------------
1 | ;
2 | ; G O T H I C 2
3 | ;
4 | ; INI-File
5 | ;
6 | ; contains different settings
7 | ; ... some can be modified in gothics menu
8 | ; ... some not (feel free to hack, but don't cry ... :)
9 | ; ... others won't take any effect (they will be reset during gameplay)
10 | ; ... and a few may cause a crash or some other funny things :)
11 | ;
12 | ; Be careful but DON'T PANIC !!
13 | ;
14 |
15 |
16 |
17 | [PERFORMANCE]
18 |
19 | recalc=0
20 | ; ... indicates if your performance-settings should be recalculated (1) {analyses you computer} or not (0). Replays Intro-Video.
21 |
22 | sightValue=14
23 | ; ... range of visibility: 0=20% ... 14=300%, default is 4 (100%)
24 |
25 | modelDetail=1
26 | ; ... detail of models (LODing) from 0.0 to 1.0, default is 0.5
27 |
28 |
29 |
30 | [GAME]
31 |
32 | animatedWindows=1
33 | ; ... turn fading of game-internal windows(views) off (0) or on (1), default is 1
34 |
35 | camLookaroundInverse=0
36 | ; ... inverts the camera-lookaround for UP and DOWN-direction (for both: mouse and keyboard)
37 |
38 | bloodDetail=2
39 | ; ... details of blood (0 = off), use values from 0 to 3
40 |
41 | extendedVideoKeys=0
42 | ; ... enables extra keys for videoplay: HOME (restart), RIGHT (step forward), UP, DOWN (volume), Q(uiet), default is 0
43 |
44 | scaleVideos=1
45 | ; ... disable scaling of videos (0) if you have problems with your graphics-adapter, default is on (1)
46 |
47 | cameraLightRange=0
48 | ; ... range of cameralight in cm, default is 0 (no camera-light)
49 |
50 | invShowArrows=1
51 | ; ... show arrows beside inventory if there are more items above or beyond, default is 1
52 |
53 | invSwitchToFirstCategory=0
54 | ; ... switch to first category (weapons) in trading-screen, when moving to your heroes inventory, default is 0
55 |
56 | enableMouse=1
57 | ; ... enable your mouse for gothic, default is 0
58 |
59 | mouseSensitivity=0.5
60 | ; ... mouseSpeed in game between 0.0 and 1.0, default is 0.5
61 |
62 | playLogoVideos=1
63 | ; ... if set to 0 no intro logo videos will be played
64 |
65 | skyEffects=1
66 | ; ... turn weather-effects (rain) on (1) or off (0), default is 1
67 |
68 | highlightMeleeFocus=2
69 | ; ... here you can turn on an optional focus highlight effect during fighting
70 |
71 | highlightInteractFocus=0
72 | ; ... here you can turn on an optional focus highlight during interactions
73 |
74 | useGothic1Controls=1
75 | ; ... if you set this one to 0 you will have another fight interface (one key to attack).
76 | ; we feel the gothic 1 interface is more challenging, so we set the old controls to default
77 | ; with the new interface, the focus nsc stays locked until you move the mouse. in this mode
78 | ; the side attacks are being accessed with additional side attack keys.
79 |
80 | disallowVideoInput=0
81 | ; ... set to 1 if you dont want to have keyboard control over video sequences (default: 0)
82 |
83 | keyDelayRate=150
84 | ; ... sets the keyboard repeat delay rate in msec (default: 150)
85 |
86 | enableJoystick=0
87 | ; ... enables joystick support in gothic (default: 1) set to 0 if you encounter problems (rapid fire etc.)
88 |
89 | keyDelayFirst=0
90 | ; ... delay for first keyboard repeat in msec (default: 0)
91 |
92 | subTitles=1
93 | ; ... choose if you want to see windows with spoken words (1) or not (0), default is 0
94 |
95 | subTitlesAmbient=1
96 | ; ... set to 1 if you dont want to have subtitles for ambient talks (default: 1) [disabled if subTitles is off]
97 |
98 | subTitlesPlayer=1
99 | ; ... activates (1) or deactivates (0) subtitles for the hero (default: 1) [disabled if subTitles is off]
100 |
101 | subTitlesNoise=0
102 | ; ... activates (1) or deactivates (0) subtitles for surroundings npc ambient infos and talks (default: 0) [disabled if subTitles is off]
103 |
104 | invMaxColumns=5
105 | ; ... determins how many colums you can see with you inventory (default: 5) [0: limited by resolution]
106 |
107 | invMaxRows=0
108 | ; ... determins how many rows you can see with you inventory (default: 0: limited by resolution)
109 |
110 | invSplitScreen=1
111 | ; ... determins if you can see a second inventory during object interaction and trading. TAB will toggle inventory focus or close your inventory depending on the setting
112 |
113 | invCatOrder=COMBAT,POTION,FOOD,ARMOR,MAGIC,RUNE,DOCS,OTHER,NONE
114 | ; ... determins the inventory item group order.
115 |
116 | gametextAutoScroll=1000
117 | ; ... with this value you can tune the scroll time in msec of the various in game infos (default: 1000)
118 |
119 | usePotionKeys=0
120 | ; ... with this value you are allowed to use the potion keys if set to "1". potionkeys do not work and are not visible in the keyboard settings if you leave this to "0"
121 | ; we feel potion shortkeys suck in gameplay, so you will manually have to enable them here
122 |
123 | useQuickSaveKeys=0
124 | ; ... with this value set to "1" you quicksave and quickload slots will be enabled in the savegame screen. press "F5" to quicksave and "F9" to quickload
125 | ; this feature is not testet good enough yet, and therefore it is disabled for goldmaster. you may enable it at your own risk by setting it to "1"
126 |
127 | useSpeechReverbLevel=2
128 | ; ... with this setting you can enable several reverb-settings for in-game-speech. 0: no reverb, 1: slight reverb, 2: full reverb (default: 2)
129 |
130 | keyboardLayout=00020409
131 | ; ... currently there are two supported keyboard layouts: 00000407 - German, 00020409 - US-International
132 | ; ( see http://www.microsoft.com/globaldev/keyboards/keyboards.asp , dead keys are not supportet at all )
133 |
134 | pickLockScramble=0
135 | ; ... you can increase the feeling of lockpicking if you enable scrambling the combination on loading an savegame
136 | ; the value is the maximum length of combination which will be scrambled, 0 = off (default)
137 |
138 | PATCHVERSION=5
139 | SHORTKEY1FARPLANEDIST=0.8
140 | SHORTKEY2FARPLANEDIST=1.2
141 | SHORTKEY3FARPLANEDIST=2
142 | SHORTKEY4FARPLANEDIST=3
143 | zShowWeaponTrails=1
144 | itemEffects=1
145 | spawnRemoveNpcOnlyIfEmpty=0
146 |
147 |
148 | [VIDEO]
149 |
150 | zVidDevice=0
151 | ; ... index of graphic-device beginning with zero.
152 |
153 | zVidResFullscreenX=1440
154 | zVidResFullscreenY=900
155 | zVidResFullscreenBPP=16
156 | ; ... used resolution
157 |
158 | zStartupWindowed=0
159 | ; ... should the game be started as a window-application? Just for debugging!
160 | ; ... ATTENTION: Not all resolution work in window-mode!!!
161 |
162 | zVidBrightness=0.5
163 | ; ... brightness from 0.0 (dark) to 1.0 (bright)
164 |
165 | zVidContrast=0.5
166 | ; ... contrast from 0.0 (low contrast) to 1.0 (high contrast)
167 |
168 | zVidGamma=0.5
169 | ; ... gamma from 0.0 (dark) to 1.0 (bright)
170 |
171 | zTexMaxSize=16384
172 | ; ... size of texture in pixels, default is 16384 (max)
173 |
174 |
175 |
176 | [SOUND]
177 |
178 | soundVolume=1
179 | musicVolume=0.200000003
180 | ; ... volume of sound and music, ranges between 0.0 (off) and 1.0 (noisy)
181 |
182 | musicEnabled=1
183 | ; ... enables (1) or disables (0) music. Gothic needs less memory without music.
184 |
185 | soundEnabled=1
186 | ; ... enables (1) or disables (0) sound.
187 |
188 | soundUseReverb=1
189 | ; ... enables (1) or disables (0) in game reverb effects in indoor locations.
190 |
191 | extendedProviders=0
192 | ; ... enables (1) or disables (0) some unsupported sound providers in the menu (Dolby Surround and Intel RSX; use at your own risk)
193 |
194 |
195 |
196 | [RENDERER_D3D]
197 |
198 | zFogDisabled=0
199 | ; ... diables fog. set this to 1 if you have any problem with fogging
200 |
201 | zFogRadial=1
202 | ; ... enables radial fog. this could be somehow slower on some grafic cards, but looks smoother. set to "0" if you have any problems with it
203 | ; some cards without T&L don't support radial fog. On these cards, (although they are unsupported) it may be wise to deactivate radial fog.
204 |
205 | zVidRefreshRate=0
206 | ; ... overrides the windows default refresh rate. enter a value above 75 to make your eyes happier (default: 0)
207 | ; Attention: could collide with various refresh rate tools as nvmax, nvidia refresh rate fix, etc.. if you enter any value above "0"
208 |
209 | zForceZBuffer=0
210 | ; ... gothic first tries to activate a w buffer if your cards supports it. however, some cards have problems with gothics way to access the w buffer
211 | ; you can force z buffering here by setting the value to "1"
212 |
213 | zEnableTaskSwitch=1
214 | ; ... enables (1) or disables (0) going to windowed/pause mode if gothic 2 looses focus (e.g. on ALT-Tab)
215 |
216 | geforce3HackWBufferBug=1
217 | ; ... some geforce 3 or geforce 4 cards have problems with gothics way to access the w buffer, resulting in flickering polys
218 | ; in the distant. with this setting set to "1" these cards automatically use a z buffer, loosing some precision near the camera but without the flickering polys.
219 | ; the driver version 12.41 does not have this problem. if you you have this version installed you may set this to 0 in order to activate the better looking
220 | ; w buffer. Driver versions later than 30.82 may not have this problem either.
221 |
222 |
223 | zSyncAmbientCol=0
224 | ; ... some grafic drivers have problems with gothics way to access the ambient lightning on a per object base but want the ambient
225 | ; light on a per scene base. this is a driver bug! if there occurs heavily lightning flickering with objects, you might set this setting
226 | ; to "1" to synchronize the ambient color after each object. this forces the driver to flush the scene after each objects which can
227 | ; seriously degrade performance (especially if you activate antialiasing!)
228 |
229 | radeonHackAmbientColBug=0
230 | ; ... the radeon 9700 has known problems with accessing the ambient lightning on a per object base, thus using the above "zSyncAmbientCol"
231 | ; Feature automatically. By activating the workaround for this card, performance may drop about 10%. Fullscene antialiasing does not work
232 | ; fast enough on this card until ATI fixes the ambient col driver bug.
233 | ; if you set this setting to "0" and no object lightning flickering occurs, ATI has probably managed to fix the problem and you may enable antialiasing
234 |
235 |
236 | [SKY_OUTDOOR]
237 |
238 | zDayColor0=82 109 198
239 | zDayColor1=255 255 0
240 | zDayColor2=18 16 60
241 | zDayColor3=134 104 125
242 | zDayColor0_OW=90 80 80
243 | zDayColor1_OW=90 80 80
244 | zDayColor2_OW=90 80 80
245 | zDayColor3_OW=90 80 80
246 | ; ... these values tune the different sky colors during different daytimes
247 |
248 | zSkyDome=1
249 | ; ... here you can define if you want a smooth sky sphere instead of a sky plane. enter a "0" here if you want more performance. (default:1)
250 |
251 | zColorizeSky=1
252 | ; ... with this value you can make the skysphere even more beautiful (set it to "0" for a plus of performance) (default:1)
253 |
254 | zSunName=unsun5.tga
255 | zSunSize=200
256 | zSunAlpha=230
257 | zMoonName=moon.tga
258 | zMoonSize=400
259 | zMoonAlpha=255
260 | ; ... these values tune the different sizes and alpha intensitys of the sky planets. you should leave them as they are :)
261 |
262 | zRainWindScale=0.003
263 | ; ... this value tunes how wind affects the rain. looks great with higher values, but occasional you will see rain drops in indoor locations
264 |
265 | zNearFogScale=1
266 | zFarFogScale=1
267 | ; ... these settings tune the far- and near-fog distances (default: 1, range: 0.0 - 1.0)
268 |
269 |
270 |
271 | [ENGINE]
272 |
273 | zDetailTexturesEnabled=1
274 | ; ... here you can define if the engine should support detail textures (default: 1)
275 |
276 | zSubdivSurfacesEnabled=0
277 | ; ... with this setting you can activate subdiving surface for progressive meshes (untestet, default: 0)
278 |
279 | zTexCacheOutTimeMSec=240000
280 | zTexCacheSizeMaxBytes=32000000
281 | zSndCacheOutTimeMSec=10000
282 | zSndCacheSizeMaxBytes=20000000
283 | ; ... with these settings you can tune the memory usage of the texture and sound resources.
284 | ; if you have more ram than 512 MB, greater values will improve performance
285 |
286 | zVobFarClipZScale=14
287 | ; ... with this setting you can tune the object visibility range. (range: 1..3) default: 1
288 |
289 | zFarClipAlphaFade=1
290 | ; ... enables (1) or disables (0) water distance fade and camera angle transparency dependencies. disabling improves performance
291 |
292 | zEnvMapTextureName=zflare1.tga
293 | ; ... texture name for the object env effects
294 |
295 | zWaterAniEnabled=1
296 | ; ... enables (1) or disables (0) water waves. disabling improves performance
297 |
298 | zWaterEnvMapTextureName=cloudenv_bright.tga
299 | ; ... texture name for the water env effect
300 |
301 | zWaterEnvMapAniFPS=0
302 | ; ... animation speed in for an optional water env texture
303 |
304 | zHighLightScale=0
305 | ; ... enables (1) or disables (0) item highlight swell (default: 0)
306 |
307 | ZMAXFPS=0
308 | ; ... some strange gfx hardware may have problems with gothic's way accessing the game-timer. you may limit the maximum fps rate with entering any value
309 | ; above 1. (The spacer needs a reasonably value here especially for editing very small ZENs)
310 |
311 | zSmoothTimer=1
312 | ; ... enables (1) or disables (0) smoothing of the in-game timer so that animations will look smoother during short sloppy framerates
313 | ; (default: 1)
314 |
315 | zVidEnableAntiAliasing=0
316 | ; ... enables (1) or disables (0) edge antialiasing. this is driver dependant and a performance hit.
317 |
318 | zSmoothModelRootNode=1
319 | ; ... enables (1) or disables (0) model moving smooting (default: 1)
320 |
321 | zMouseRotationScale=2.0
322 | ; ... this value affects the npc turning speed while using your mouse. Attention: can seriously affect gameplay if setting to unreasonably values (default: 2.0)
323 |
324 | zDontSwitchToThirdPerson=0
325 | ; ... enables (1) or disables (0) auto-switching the camera to 3rd person during dialogs, interactions and combat.
326 | ; Attention: seriously affects gameplay if setting to "1", as everything can be done in 1st person, untested feature but fun
327 |
328 | zCacheInAllNSCAtNewGame=0
329 | ; ... with this value setting to "0" you can achive a plus of startup time, as several humans won't be loaded in memory on startup
330 |
331 | zCloudShadowScale=1
332 | ; ... this value enables (1) or disables (0) the cloudshadow effect during raining. range: (0.0-1.0) default: 0.0. attention: performance hog!
333 |
334 | zTexAnisotropicFiltering=0
335 | ; ... enables (1) or disables (0) anisotropic filtering for textures. this is driver dependant and a performance hit, but improves texture sharpness
336 | ; default: 0
337 |
338 | NOAMBIENTPFX=0
339 | ; ... enables (0) or disables (1) rendering of ambient particles during gameplay. if you have a card with a lesser fillrate, you should set this to "1"
340 | ; in order to improve speed
341 |
342 | zVobPointLight=1
343 | ; ... enables (1) or disables (0) additional dynamic lights for indoor objects, greatly improving details. you should left this as it is, although in can improve indoor performance.
344 |
345 | ZNEARVALUE=-1
346 | ; ... with this setting you may fine-tune the distant-value of the near clipping plane. some cards may accept more aggresive near z values then the default calculated
347 | ; by gothic. (w buffering uses alway a value of 1, so you don't need to fine-tune this setting) (default: -1, let the value determin by renderer)
348 |
349 | zSkyRenderFirst=1
350 | ; ... enables (0) or disables (1) an additional way to workaround the flickering poly in the distant on geforce 3 or geforce 4 cards.
351 | ; if you set this to "0" the sky will be renderer after the normal game world thus overlaying the flickering polys. this does only work with 32 bit
352 | ; color enabled and if you set the value "geforce3HackWBufferBug" to "0". the drawback is that the sky is slightly distorted, but this should be the best
353 | ; workaround for most geforce 3/4 users as the flicker polys are more annoying. moreover you can't see through walls with this workaround any more
354 | ; (default: 1)
355 |
356 | zMaxFPS=0
357 | ; ... some rare gfx hardware may have problems with gothics way to access the timer, resulting in jerky animations.
358 | ; with this setting set to a fixed value (e.g. 20) you can avoid choppy animations on those systems
359 | ; the spacer needs a fixed value here in order to work properly during editing small ZEN Files
360 |
361 | zAmbientPFXEnabled=1
362 | ; ... enables (1) or disables (0) rendering of ambient particles. rendering ambient particles greatly limits your fillrate, so if you have a card with less
363 | ; fill-rate capabilities (e.g. geforce 2 MX versions) you may set this to "0" to improve performance. (default: 1)
364 |
365 | zAmbientVobsEnabled=1
366 | ; ... enables (1) or disables (0) rendering of ambient objects. not used in gothic 2
367 |
368 | zEnvMappingEnabled=1
369 | ; ... enables (1) or disables (0) rendering of environmental effects (aka shiny/reflective surfaces). improves performance if deactivated (default: 1)
370 |
371 | zKillSysKeys=0
372 | ; ... enables (1) or disables (0) the window keys as ALT-TAB, ALT-ESC, etc... GOTHIC handles focus-loss by going to windowed-pause mode, so
373 | ; there is no real need to deactivate the keys (moreover, disallowing those keys is more of a hack than a feature).
374 | ; this feature is untested and unsupported.
375 |
376 | zSmoothMouse=3
377 | ; ... with this setting you can smooth your mouse movements by averaging the last [n] frame moves. higher values result in laggier but smoother mouse response.
378 | ; (default: 3) ATTENTION: modifying this value may result in different gameplay.
379 |
380 | zMusic16ChannelsOnly=0
381 | ; ... if you have 256 MB or less memory, you can force the music system to use only 16 channels, thus killing several instruments and performances.
382 | ; ATTENTION: setting this to "1" reduces music quality but can improve performance. If music is not important for you, you have the choice to only
383 | ; use 16 channels.
384 |
385 | zInventoryItemsDistanceScale=1.3
386 | ; ... some rare grafic cards have a high near clipping value resulting in inventory items not being visible (esp. if you have the cursor focus on it)
387 | ; with entering a value above "0" you can scale the item distances from the camera in order to make the items smaller, but visible
388 | ; (e.g. with a value of 2.0 the items will be twice as far away from the camera)
389 | ; range: 0..1000. (default: 1.3)
390 |
391 | zWindEnabled=1
392 | ; ... enables (1) or disables (0) in-game wind for objects/trees etc. improves performance (especially on slow cpu's) (default: 1)
393 |
394 | zWindCycleTime=4
395 | zWindCycleTimeVar=2
396 | zWindStrength=70
397 | zWindStrengthVar=40
398 | zWindAngleVelo=0.9
399 | zWindAngleVeloVar=0.8
400 | ; ... these settings tune the wind effect, you should leave them as they are (altough funny things can happen;)
401 |
402 | zSunMaxScreenBlendScale=0.8
403 | zRayTurboPolyTreshold=500
404 |
405 |
406 |
407 | [KEYS]
408 | keyEnd=0100
409 | keyHeal=2300
410 | keyPotion=1900
411 | keyLockTarget=4f00
412 | keyParade=cf000d02
413 | keyActionRight=d100
414 | keyActionLeft=d300
415 | keyUp=c8001100
416 | keyDown=d0001f00
417 | keyLeft=cb001000
418 | keyRight=cd001200
419 | keyStrafeLeft=d3001e00
420 | keyStrafeRight=d1002000
421 | keyAction=1d000c02
422 | keySlow=2a003600
423 | keySMove=38009d00
424 | keyWeapon=39000e02
425 | keySneak=2d00
426 | keyLook=13005200
427 | keyLookFP=21005300
428 | keyInventory=0f000e00
429 | keyShowStatus=30002e00
430 | keyShowLog=31002600
431 | keyShowMap=3200
432 |
433 | [KEYSDEFAULT0]
434 | keyEnd=0100
435 | keyHeal=2300
436 | keyPotion=1900
437 | keyLockTarget=4f00
438 | keyParade=cf000d02
439 | keyActionRight=d100
440 | keyActionLeft=d300
441 | keyUp=c8001100
442 | keyDown=d0001f00
443 | keyLeft=cb001000
444 | keyRight=cd001200
445 | keyStrafeLeft=d3001e00
446 | keyStrafeRight=d1002000
447 | keyAction=1d000c02
448 | keySlow=2a003600
449 | keySMove=38009d00
450 | keyWeapon=39000e02
451 | keySneak=2d00
452 | keyLook=13005200
453 | keyLookFP=21005300
454 | keyInventory=0f000e00
455 | keyShowStatus=30002e00
456 | keyShowLog=31002600
457 | keyShowMap=3200
458 |
459 | [KEYSDEFAULT1]
460 | keyEnd=0100
461 | keyHeal=2300
462 | keyPotion=1900
463 | keyLockTarget=4f00
464 | keyParade=cf000d02
465 | keyActionRight=d100
466 | keyActionLeft=d300
467 | keyUp=c8001100
468 | keyDown=d0001f00
469 | keyLeft=1000
470 | keyRight=1200
471 | keyStrafeLeft=cb001e00
472 | keyStrafeRight=cd002000
473 | keyAction=1d000c02
474 | keySlow=2a003600
475 | keySMove=38009d00
476 | keyWeapon=39000e02
477 | keySneak=2d00
478 | keyLook=13005200
479 | keyLookFP=21005300
480 | keyInventory=0f000e00
481 | keyShowStatus=30002e00
482 | keyShowLog=31002600
483 | keyShowMap=3200
484 |
485 |
486 | [INTERNAL]
487 | idComputerName=DELL-INSPIRON-5
488 | idUserName=Salaros
489 | extendedMenu=0
490 | gameStarts=7
491 | perfQualityIndex=0
492 | gameStartFailed=0
493 | gameAbnormalExit=0
494 | menuShowVersion=1
495 | gamePath=
496 | gameScript=
497 | gameCompile=1.0
498 | playerInstanceName=
499 | menuAction=LEAVE_GAME
500 | debugAllChannels=0
501 | debugAllInstances=0
502 | debugChannels=
503 | cutscenesDisabled=0
504 | texDetailIndex=1
505 | vidResIndex=15
506 | soundProviderIndex=0
507 | soundSampleRateIndex=1
508 | soundSpeakerIndex=1
509 | logStatistics=0
510 | zFastSaveGames=1
511 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/ROTK.ini:
--------------------------------------------------------------------------------
1 | [input0]
2 | map=ROTKDefault
3 | mode=KB
4 | InputPolling=1
5 | [input1]
6 | map=ROTKDefault
7 | mode=KB
8 | [input_KB_BASE_0]
9 | ROOT_MAP = ROTKDefault
10 | CTRL_BUTTON_RIGHT_TOP = KEYID_E
11 | CTRL_BUTTON_RIGHT_DPAD_UP = MOUSEID_BUTTON_2
12 | CTRL_BUTTON_RIGHT_DPAD_UP = KEYID_NUMPAD8
13 | CTRL_BUTTON_RIGHT_BOTTOM = KEYID_SPACE
14 | CTRL_BUTTON_RIGHT_DPAD_LEFT = MOUSEID_BUTTON_3
15 | CTRL_BUTTON_RIGHT_DPAD_LEFT = KEYID_NUMPAD4
16 | CTRL_BUTTON_RIGHT_DPAD_RIGHT = KEYID_LCONTROL
17 | CTRL_BUTTON_RIGHT_DPAD_RIGHT = KEYID_NUMPAD6
18 | CTRL_BUTTON_LEFT_TOP = KEYID_LSHIFT
19 | CTRL_BUTTON_RIGHT_DPAD_DOWN = MOUSEID_BUTTON_1
20 | CTRL_BUTTON_RIGHT_DPAD_DOWN = KEYID_NUMPAD2
21 | CTRL_BUTTON_START = KEYID_ESC
22 | CTRL_BUTTON_LEFT_BOTTOM = KEYID_TAB
23 | CTRL_BUTTON_SELECT = KEYID_BACK
24 | CTRL_BUTTON_LEFT_STICK = KEYID_F5
25 | LEFT_ANALOG_X = MOUSE(200),0
26 | LEFT_ANALOG_Y = MOUSE(200),0
27 | LEFT_ANALOG_EX_AUTO_NORTH = KEYID_W
28 | LEFT_ANALOG_EX_AUTO_WEST = KEYID_A
29 | LEFT_ANALOG_EX_AUTO_SOUTH = KEYID_S
30 | LEFT_ANALOG_EX_AUTO_EAST = KEYID_D
31 | MOUSE_CLAMP_POS = 0,0,0,0,1,200
32 | [input_KB_BASE_1]
33 | ROOT_MAP = ROTKDefault
34 | CTRL_BUTTON_RIGHT_TOP = KEYID_E
35 | CTRL_BUTTON_RIGHT_DPAD_UP = MOUSEID_BUTTON_2
36 | CTRL_BUTTON_RIGHT_DPAD_UP = KEYID_NUMPAD8
37 | CTRL_BUTTON_RIGHT_BOTTOM = KEYID_SPACE
38 | CTRL_BUTTON_RIGHT_BOTTOM = MOUSEID_BUTTON_3
39 | CTRL_BUTTON_RIGHT_DPAD_LEFT = KEYID_Q
40 | CTRL_BUTTON_RIGHT_DPAD_LEFT = KEYID_NUMPAD4
41 | CTRL_BUTTON_RIGHT_DPAD_RIGHT = KEYID_LCONTROL
42 | CTRL_BUTTON_RIGHT_DPAD_RIGHT = KEYID_NUMPAD6
43 | CTRL_BUTTON_LEFT_TOP = KEYID_LSHIFT
44 | CTRL_BUTTON_RIGHT_DPAD_DOWN = MOUSEID_BUTTON_1
45 | CTRL_BUTTON_RIGHT_DPAD_DOWN = KEYID_NUMPAD2
46 | CTRL_BUTTON_START = KEYID_ESC
47 | CTRL_BUTTON_LEFT_BOTTOM = KEYID_TAB
48 | CTRL_BUTTON_SELECT = KEYID_BACK
49 | CTRL_BUTTON_LEFT_STICK = KEYID_F5
50 | LEFT_ANALOG_X = MOUSE(200),0
51 | LEFT_ANALOG_Y = MOUSE(200),0
52 | LEFT_ANALOG_EX_AUTO_NORTH = KEYID_W
53 | LEFT_ANALOG_EX_AUTO_WEST = KEYID_A
54 | LEFT_ANALOG_EX_AUTO_SOUTH = KEYID_S
55 | LEFT_ANALOG_EX_AUTO_EAST = KEYID_D
56 | MOUSE_CLAMP_POS = 0,0,0,0,1,200
57 | [GamePlay]
58 | Difficulty=0
59 | Subtitles=0
60 | Player1Indicator=0
61 | Player2Indicator=0
62 | [Video]
63 | AdapterNumber=0
64 | Width=1024
65 | Gamma=0.850000
66 | Enable32Bit=1
67 | EnableShadows=1
68 | EnableSimpleShadows=0
69 | AlternateCameras=1
70 | LowResTexture=0
71 | SfxMode=2
72 | [Audio]
73 | Volume_Music=100
74 | Volume_Voice=100
75 | Volume_Sfx=100
76 | AudioMode=0
77 | Software_Stream_Buffers=0
78 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/main.cf.default:
--------------------------------------------------------------------------------
1 | # Global Postfix configuration file. This file lists only a subset
2 | # of all parameters. For the syntax, and for a complete parameter
3 | # list, see the postconf(5) manual page (command: "man 5 postconf").
4 | #
5 | # For common configuration examples, see BASIC_CONFIGURATION_README
6 | # and STANDARD_CONFIGURATION_README. To find these documents, use
7 | # the command "postconf html_directory readme_directory", or go to
8 | # http://www.postfix.org/.
9 | #
10 | # For best results, change no more than 2-3 parameters at a time,
11 | # and test if Postfix still works after every change.
12 |
13 | # SOFT BOUNCE
14 | #
15 | # The soft_bounce parameter provides a limited safety net for
16 | # testing. When soft_bounce is enabled, mail will remain queued that
17 | # would otherwise bounce. This parameter disables locally-generated
18 | # bounces, and prevents the SMTP server from rejecting mail permanently
19 | # (by changing 5xx replies into 4xx replies). However, soft_bounce
20 | # is no cure for address rewriting mistakes or mail routing mistakes.
21 | #
22 | #soft_bounce = no
23 |
24 | # LOCAL PATHNAME INFORMATION
25 | #
26 | # The queue_directory specifies the location of the Postfix queue.
27 | # This is also the root directory of Postfix daemons that run chrooted.
28 | # See the files in examples/chroot-setup for setting up Postfix chroot
29 | # environments on different UNIX systems.
30 | #
31 | queue_directory = /var/spool/postfix
32 |
33 | # The command_directory parameter specifies the location of all
34 | # postXXX commands.
35 | #
36 | command_directory = /usr/sbin
37 |
38 | # The daemon_directory parameter specifies the location of all Postfix
39 | # daemon programs (i.e. programs listed in the master.cf file). This
40 | # directory must be owned by root.
41 | #
42 | daemon_directory = /usr/libexec/postfix
43 |
44 | # QUEUE AND PROCESS OWNERSHIP
45 | #
46 | # The mail_owner parameter specifies the owner of the Postfix queue
47 | # and of most Postfix daemon processes. Specify the name of a user
48 | # account THAT DOES NOT SHARE ITS USER OR GROUP ID WITH OTHER ACCOUNTS
49 | # AND THAT OWNS NO OTHER FILES OR PROCESSES ON THE SYSTEM. In
50 | # particular, don't specify nobody or daemon. PLEASE USE A DEDICATED
51 | # USER.
52 | #
53 | mail_owner = postfix
54 |
55 | # The default_privs parameter specifies the default rights used by
56 | # the local delivery agent for delivery to external file or command.
57 | # These rights are used in the absence of a recipient user context.
58 | # DO NOT SPECIFY A PRIVILEGED USER OR THE POSTFIX OWNER.
59 | #
60 | #default_privs = nobody
61 |
62 | # INTERNET HOST AND DOMAIN NAMES
63 | #
64 | # The myhostname parameter specifies the internet hostname of this
65 | # mail system. The default is to use the fully-qualified domain name
66 | # from gethostname(). $myhostname is used as a default value for many
67 | # other configuration parameters.
68 | #
69 | #myhostname = host.domain.tld
70 | #myhostname = virtual.domain.tld
71 |
72 | # The mydomain parameter specifies the local internet domain name.
73 | # The default is to use $myhostname minus the first component.
74 | # $mydomain is used as a default value for many other configuration
75 | # parameters.
76 | #
77 | #mydomain = domain.tld
78 |
79 | # SENDING MAIL
80 | #
81 | # The myorigin parameter specifies the domain that locally-posted
82 | # mail appears to come from. The default is to append $myhostname,
83 | # which is fine for small sites. If you run a domain with multiple
84 | # machines, you should (1) change this to $mydomain and (2) set up
85 | # a domain-wide alias database that aliases each user to
86 | # user@that.users.mailhost.
87 | #
88 | # For the sake of consistency between sender and recipient addresses,
89 | # myorigin also specifies the default domain name that is appended
90 | # to recipient addresses that have no @domain part.
91 | #
92 | #myorigin = $myhostname
93 | #myorigin = $mydomain
94 |
95 | # RECEIVING MAIL
96 |
97 | # The inet_interfaces parameter specifies the network interface
98 | # addresses that this mail system receives mail on. By default,
99 | # the software claims all active interfaces on the machine. The
100 | # parameter also controls delivery of mail to user@[ip.address].
101 | #
102 | # See also the proxy_interfaces parameter, for network addresses that
103 | # are forwarded to us via a proxy or network address translator.
104 | #
105 | # Note: you need to stop/start Postfix when this parameter changes.
106 | #
107 | #inet_interfaces = all
108 | #inet_interfaces = $myhostname
109 | #inet_interfaces = $myhostname, localhost
110 | inet_interfaces = localhost
111 |
112 | # The proxy_interfaces parameter specifies the network interface
113 | # addresses that this mail system receives mail on by way of a
114 | # proxy or network address translation unit. This setting extends
115 | # the address list specified with the inet_interfaces parameter.
116 | #
117 | # You must specify your proxy/NAT addresses when your system is a
118 | # backup MX host for other domains, otherwise mail delivery loops
119 | # will happen when the primary MX host is down.
120 | #
121 | #proxy_interfaces =
122 | #proxy_interfaces = 1.2.3.4
123 |
124 | # The mydestination parameter specifies the list of domains that this
125 | # machine considers itself the final destination for.
126 | #
127 | # These domains are routed to the delivery agent specified with the
128 | # local_transport parameter setting. By default, that is the UNIX
129 | # compatible delivery agent that lookups all recipients in /etc/passwd
130 | # and /etc/aliases or their equivalent.
131 | #
132 | # The default is $myhostname + localhost.$mydomain. On a mail domain
133 | # gateway, you should also include $mydomain.
134 | #
135 | # Do not specify the names of virtual domains - those domains are
136 | # specified elsewhere (see VIRTUAL_README).
137 | #
138 | # Do not specify the names of domains that this machine is backup MX
139 | # host for. Specify those names via the relay_domains settings for
140 | # the SMTP server, or use permit_mx_backup if you are lazy (see
141 | # STANDARD_CONFIGURATION_README).
142 | #
143 | # The local machine is always the final destination for mail addressed
144 | # to user@[the.net.work.address] of an interface that the mail system
145 | # receives mail on (see the inet_interfaces parameter).
146 | #
147 | # Specify a list of host or domain names, /file/name or type:table
148 | # patterns, separated by commas and/or whitespace. A /file/name
149 | # pattern is replaced by its contents; a type:table is matched when
150 | # a name matches a lookup key (the right-hand side is ignored).
151 | # Continue long lines by starting the next line with whitespace.
152 | #
153 | # See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
154 | #
155 | #mydestination = $myhostname, localhost.$mydomain, localhost
156 | #mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
157 | #mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,
158 | # mail.$mydomain, www.$mydomain, ftp.$mydomain
159 |
160 | # REJECTING MAIL FOR UNKNOWN LOCAL USERS
161 | #
162 | # The local_recipient_maps parameter specifies optional lookup tables
163 | # with all names or addresses of users that are local with respect
164 | # to $mydestination, $inet_interfaces or $proxy_interfaces.
165 | #
166 | # If this parameter is defined, then the SMTP server will reject
167 | # mail for unknown local users. This parameter is defined by default.
168 | #
169 | # To turn off local recipient checking in the SMTP server, specify
170 | # local_recipient_maps = (i.e. empty).
171 | #
172 | # The default setting assumes that you use the default Postfix local
173 | # delivery agent for local delivery. You need to update the
174 | # local_recipient_maps setting if:
175 | #
176 | # - You define $mydestination domain recipients in files other than
177 | # /etc/passwd, /etc/aliases, or the $virtual_alias_maps files.
178 | # For example, you define $mydestination domain recipients in
179 | # the $virtual_mailbox_maps files.
180 | #
181 | # - You redefine the local delivery agent in master.cf.
182 | #
183 | # - You redefine the "local_transport" setting in main.cf.
184 | #
185 | # - You use the "luser_relay", "mailbox_transport", or "fallback_transport"
186 | # feature of the Postfix local delivery agent (see local(8)).
187 | #
188 | # Details are described in the LOCAL_RECIPIENT_README file.
189 | #
190 | # Beware: if the Postfix SMTP server runs chrooted, you probably have
191 | # to access the passwd file via the proxymap service, in order to
192 | # overcome chroot restrictions. The alternative, having a copy of
193 | # the system passwd file in the chroot jail is just not practical.
194 | #
195 | # The right-hand side of the lookup tables is conveniently ignored.
196 | # In the left-hand side, specify a bare username, an @domain.tld
197 | # wild-card, or specify a user@domain.tld address.
198 | #
199 | #local_recipient_maps = unix:passwd.byname $alias_maps
200 | #local_recipient_maps = proxy:unix:passwd.byname $alias_maps
201 | #local_recipient_maps =
202 |
203 | # The unknown_local_recipient_reject_code specifies the SMTP server
204 | # response code when a recipient domain matches $mydestination or
205 | # ${proxy,inet}_interfaces, while $local_recipient_maps is non-empty
206 | # and the recipient address or address local-part is not found.
207 | #
208 | # The default setting is 550 (reject mail) but it is safer to start
209 | # with 450 (try again later) until you are certain that your
210 | # local_recipient_maps settings are OK.
211 | #
212 | unknown_local_recipient_reject_code = 550
213 |
214 | # TRUST AND RELAY CONTROL
215 |
216 | # The mynetworks parameter specifies the list of "trusted" SMTP
217 | # clients that have more privileges than "strangers".
218 | #
219 | # In particular, "trusted" SMTP clients are allowed to relay mail
220 | # through Postfix. See the smtpd_recipient_restrictions parameter
221 | # in postconf(5).
222 | #
223 | # You can specify the list of "trusted" network addresses by hand
224 | # or you can let Postfix do it for you (which is the default).
225 | #
226 | # By default (mynetworks_style = subnet), Postfix "trusts" SMTP
227 | # clients in the same IP subnetworks as the local machine.
228 | # On Linux, this does works correctly only with interfaces specified
229 | # with the "ifconfig" command.
230 | #
231 | # Specify "mynetworks_style = class" when Postfix should "trust" SMTP
232 | # clients in the same IP class A/B/C networks as the local machine.
233 | # Don't do this with a dialup site - it would cause Postfix to "trust"
234 | # your entire provider's network. Instead, specify an explicit
235 | # mynetworks list by hand, as described below.
236 | #
237 | # Specify "mynetworks_style = host" when Postfix should "trust"
238 | # only the local machine.
239 | #
240 | #mynetworks_style = class
241 | #mynetworks_style = subnet
242 | #mynetworks_style = host
243 |
244 | # Alternatively, you can specify the mynetworks list by hand, in
245 | # which case Postfix ignores the mynetworks_style setting.
246 | #
247 | # Specify an explicit list of network/netmask patterns, where the
248 | # mask specifies the number of bits in the network part of a host
249 | # address.
250 | #
251 | # You can also specify the absolute pathname of a pattern file instead
252 | # of listing the patterns here. Specify type:table for table-based lookups
253 | # (the value on the table right-hand side is not used).
254 | #
255 | #mynetworks = 168.100.189.0/28, 127.0.0.0/8
256 | #mynetworks = $config_directory/mynetworks
257 | #mynetworks = hash:/etc/postfix/network_table
258 |
259 | # The relay_domains parameter restricts what destinations this system will
260 | # relay mail to. See the smtpd_recipient_restrictions description in
261 | # postconf(5) for detailed information.
262 | #
263 | # By default, Postfix relays mail
264 | # - from "trusted" clients (IP address matches $mynetworks) to any destination,
265 | # - from "untrusted" clients to destinations that match $relay_domains or
266 | # subdomains thereof, except addresses with sender-specified routing.
267 | # The default relay_domains value is $mydestination.
268 | #
269 | # In addition to the above, the Postfix SMTP server by default accepts mail
270 | # that Postfix is final destination for:
271 | # - destinations that match $inet_interfaces or $proxy_interfaces,
272 | # - destinations that match $mydestination
273 | # - destinations that match $virtual_alias_domains,
274 | # - destinations that match $virtual_mailbox_domains.
275 | # These destinations do not need to be listed in $relay_domains.
276 | #
277 | # Specify a list of hosts or domains, /file/name patterns or type:name
278 | # lookup tables, separated by commas and/or whitespace. Continue
279 | # long lines by starting the next line with whitespace. A file name
280 | # is replaced by its contents; a type:name table is matched when a
281 | # (parent) domain appears as lookup key.
282 | #
283 | # NOTE: Postfix will not automatically forward mail for domains that
284 | # list this system as their primary or backup MX host. See the
285 | # permit_mx_backup restriction description in postconf(5).
286 | #
287 | #relay_domains = $mydestination
288 |
289 | # INTERNET OR INTRANET
290 |
291 | # The relayhost parameter specifies the default host to send mail to
292 | # when no entry is matched in the optional transport(5) table. When
293 | # no relayhost is given, mail is routed directly to the destination.
294 | #
295 | # On an intranet, specify the organizational domain name. If your
296 | # internal DNS uses no MX records, specify the name of the intranet
297 | # gateway host instead.
298 | #
299 | # In the case of SMTP, specify a domain, host, host:port, [host]:port,
300 | # [address] or [address]:port; the form [host] turns off MX lookups.
301 | #
302 | # If you're connected via UUCP, see also the default_transport parameter.
303 | #
304 | #relayhost = $mydomain
305 | #relayhost = [gateway.my.domain]
306 | #relayhost = [mailserver.isp.tld]
307 | #relayhost = uucphost
308 | #relayhost = [an.ip.add.ress]
309 |
310 | # REJECTING UNKNOWN RELAY USERS
311 | #
312 | # The relay_recipient_maps parameter specifies optional lookup tables
313 | # with all addresses in the domains that match $relay_domains.
314 | #
315 | # If this parameter is defined, then the SMTP server will reject
316 | # mail for unknown relay users. This feature is off by default.
317 | #
318 | # The right-hand side of the lookup tables is conveniently ignored.
319 | # In the left-hand side, specify an @domain.tld wild-card, or specify
320 | # a user@domain.tld address.
321 | #
322 | #relay_recipient_maps = hash:/etc/postfix/relay_recipients
323 |
324 | # INPUT RATE CONTROL
325 | #
326 | # The in_flow_delay configuration parameter implements mail input
327 | # flow control. This feature is turned on by default, although it
328 | # still needs further development (it's disabled on SCO UNIX due
329 | # to an SCO bug).
330 | #
331 | # A Postfix process will pause for $in_flow_delay seconds before
332 | # accepting a new message, when the message arrival rate exceeds the
333 | # message delivery rate. With the default 100 SMTP server process
334 | # limit, this limits the mail inflow to 100 messages a second more
335 | # than the number of messages delivered per second.
336 | #
337 | # Specify 0 to disable the feature. Valid delays are 0..10.
338 | #
339 | #in_flow_delay = 1s
340 |
341 | # ADDRESS REWRITING
342 | #
343 | # The ADDRESS_REWRITING_README document gives information about
344 | # address masquerading or other forms of address rewriting including
345 | # username->Firstname.Lastname mapping.
346 |
347 | # ADDRESS REDIRECTION (VIRTUAL DOMAIN)
348 | #
349 | # The VIRTUAL_README document gives information about the many forms
350 | # of domain hosting that Postfix supports.
351 |
352 | # "USER HAS MOVED" BOUNCE MESSAGES
353 | #
354 | # See the discussion in the ADDRESS_REWRITING_README document.
355 |
356 | # TRANSPORT MAP
357 | #
358 | # See the discussion in the ADDRESS_REWRITING_README document.
359 |
360 | # ALIAS DATABASE
361 | #
362 | # The alias_maps parameter specifies the list of alias databases used
363 | # by the local delivery agent. The default list is system dependent.
364 | #
365 | # On systems with NIS, the default is to search the local alias
366 | # database, then the NIS alias database. See aliases(5) for syntax
367 | # details.
368 | #
369 | # If you change the alias database, run "postalias /etc/aliases" (or
370 | # wherever your system stores the mail alias file), or simply run
371 | # "newaliases" to build the necessary DBM or DB file.
372 | #
373 | # It will take a minute or so before changes become visible. Use
374 | # "postfix reload" to eliminate the delay.
375 | #
376 | #alias_maps = dbm:/etc/aliases
377 | #alias_maps = hash:/etc/aliases
378 | #alias_maps = hash:/etc/aliases, nis:mail.aliases
379 | #alias_maps = netinfo:/aliases
380 |
381 | # The alias_database parameter specifies the alias database(s) that
382 | # are built with "newaliases" or "sendmail -bi". This is a separate
383 | # configuration parameter, because alias_maps (see above) may specify
384 | # tables that are not necessarily all under control by Postfix.
385 | #
386 | #alias_database = dbm:/etc/aliases
387 | #alias_database = dbm:/etc/mail/aliases
388 | #alias_database = hash:/etc/aliases
389 | #alias_database = hash:/etc/aliases, hash:/opt/majordomo/aliases
390 |
391 | # ADDRESS EXTENSIONS (e.g., user+foo)
392 | #
393 | # The recipient_delimiter parameter specifies the separator between
394 | # user names and address extensions (user+foo). See canonical(5),
395 | # local(8), relocated(5) and virtual(5) for the effects this has on
396 | # aliases, canonical, virtual, relocated and .forward file lookups.
397 | # Basically, the software tries user+foo and .forward+foo before
398 | # trying user and .forward.
399 | #
400 | #recipient_delimiter = +
401 |
402 | # DELIVERY TO MAILBOX
403 | #
404 | # The home_mailbox parameter specifies the optional pathname of a
405 | # mailbox file relative to a user's home directory. The default
406 | # mailbox file is /var/spool/mail/user or /var/mail/user. Specify
407 | # "Maildir/" for qmail-style delivery (the / is required).
408 | #
409 | #home_mailbox = Mailbox
410 | #home_mailbox = Maildir/
411 |
412 | # The mail_spool_directory parameter specifies the directory where
413 | # UNIX-style mailboxes are kept. The default setting depends on the
414 | # system type.
415 | #
416 | #mail_spool_directory = /var/mail
417 | #mail_spool_directory = /var/spool/mail
418 |
419 | # The mailbox_command parameter specifies the optional external
420 | # command to use instead of mailbox delivery. The command is run as
421 | # the recipient with proper HOME, SHELL and LOGNAME environment settings.
422 | # Exception: delivery for root is done as $default_user.
423 | #
424 | # Other environment variables of interest: USER (recipient username),
425 | # EXTENSION (address extension), DOMAIN (domain part of address),
426 | # and LOCAL (the address localpart).
427 | #
428 | # Unlike other Postfix configuration parameters, the mailbox_command
429 | # parameter is not subjected to $parameter substitutions. This is to
430 | # make it easier to specify shell syntax (see example below).
431 | #
432 | # Avoid shell meta characters because they will force Postfix to run
433 | # an expensive shell process. Procmail alone is expensive enough.
434 | #
435 | # IF YOU USE THIS TO DELIVER MAIL SYSTEM-WIDE, YOU MUST SET UP AN
436 | # ALIAS THAT FORWARDS MAIL FOR ROOT TO A REAL USER.
437 | #
438 | #mailbox_command = /some/where/procmail
439 | #mailbox_command = /some/where/procmail -a "$EXTENSION"
440 |
441 | # The mailbox_transport specifies the optional transport in master.cf
442 | # to use after processing aliases and .forward files. This parameter
443 | # has precedence over the mailbox_command, fallback_transport and
444 | # luser_relay parameters.
445 | #
446 | # Specify a string of the form transport:nexthop, where transport is
447 | # the name of a mail delivery transport defined in master.cf. The
448 | # :nexthop part is optional. For more details see the sample transport
449 | # configuration file.
450 | #
451 | # NOTE: if you use this feature for accounts not in the UNIX password
452 | # file, then you must update the "local_recipient_maps" setting in
453 | # the main.cf file, otherwise the SMTP server will reject mail for
454 | # non-UNIX accounts with "User unknown in local recipient table".
455 | #
456 | #mailbox_transport = lmtp:unix:/file/name
457 | #mailbox_transport = cyrus
458 |
459 | # The fallback_transport specifies the optional transport in master.cf
460 | # to use for recipients that are not found in the UNIX passwd database.
461 | # This parameter has precedence over the luser_relay parameter.
462 | #
463 | # Specify a string of the form transport:nexthop, where transport is
464 | # the name of a mail delivery transport defined in master.cf. The
465 | # :nexthop part is optional. For more details see the sample transport
466 | # configuration file.
467 | #
468 | # NOTE: if you use this feature for accounts not in the UNIX password
469 | # file, then you must update the "local_recipient_maps" setting in
470 | # the main.cf file, otherwise the SMTP server will reject mail for
471 | # non-UNIX accounts with "User unknown in local recipient table".
472 | #
473 | #fallback_transport = lmtp:unix:/file/name
474 | #fallback_transport = cyrus
475 | #fallback_transport =
476 |
477 | # The luser_relay parameter specifies an optional destination address
478 | # for unknown recipients. By default, mail for unknown@$mydestination,
479 | # unknown@[$inet_interfaces] or unknown@[$proxy_interfaces] is returned
480 | # as undeliverable.
481 | #
482 | # The following expansions are done on luser_relay: $user (recipient
483 | # username), $shell (recipient shell), $home (recipient home directory),
484 | # $recipient (full recipient address), $extension (recipient address
485 | # extension), $domain (recipient domain), $local (entire recipient
486 | # localpart), $recipient_delimiter. Specify ${name?value} or
487 | # ${name:value} to expand value only when $name does (does not) exist.
488 | #
489 | # luser_relay works only for the default Postfix local delivery agent.
490 | #
491 | # NOTE: if you use this feature for accounts not in the UNIX password
492 | # file, then you must specify "local_recipient_maps =" (i.e. empty) in
493 | # the main.cf file, otherwise the SMTP server will reject mail for
494 | # non-UNIX accounts with "User unknown in local recipient table".
495 | #
496 | #luser_relay = $user@other.host
497 | #luser_relay = $local@other.host
498 | #luser_relay = admin+$local
499 |
500 | # JUNK MAIL CONTROLS
501 | #
502 | # The controls listed here are only a very small subset. The file
503 | # SMTPD_ACCESS_README provides an overview.
504 |
505 | # The header_checks parameter specifies an optional table with patterns
506 | # that each logical message header is matched against, including
507 | # headers that span multiple physical lines.
508 | #
509 | # By default, these patterns also apply to MIME headers and to the
510 | # headers of attached messages. With older Postfix versions, MIME and
511 | # attached message headers were treated as body text.
512 | #
513 | # For details, see "man header_checks".
514 | #
515 | #header_checks = regexp:/etc/postfix/header_checks
516 |
517 | # FAST ETRN SERVICE
518 | #
519 | # Postfix maintains per-destination logfiles with information about
520 | # deferred mail, so that mail can be flushed quickly with the SMTP
521 | # "ETRN domain.tld" command, or by executing "sendmail -qRdomain.tld".
522 | # See the ETRN_README document for a detailed description.
523 | #
524 | # The fast_flush_domains parameter controls what destinations are
525 | # eligible for this service. By default, they are all domains that
526 | # this server is willing to relay mail to.
527 | #
528 | #fast_flush_domains = $relay_domains
529 |
530 | # SHOW SOFTWARE VERSION OR NOT
531 | #
532 | # The smtpd_banner parameter specifies the text that follows the 220
533 | # code in the SMTP server's greeting banner. Some people like to see
534 | # the mail version advertised. By default, Postfix shows no version.
535 | #
536 | # You MUST specify $myhostname at the start of the text. That is an
537 | # RFC requirement. Postfix itself does not care.
538 | #
539 | #smtpd_banner = $myhostname ESMTP $mail_name
540 | #smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
541 |
542 | # PARALLEL DELIVERY TO THE SAME DESTINATION
543 | #
544 | # How many parallel deliveries to the same user or domain? With local
545 | # delivery, it does not make sense to do massively parallel delivery
546 | # to the same user, because mailbox updates must happen sequentially,
547 | # and expensive pipelines in .forward files can cause disasters when
548 | # too many are run at the same time. With SMTP deliveries, 10
549 | # simultaneous connections to the same domain could be sufficient to
550 | # raise eyebrows.
551 | #
552 | # Each message delivery transport has its XXX_destination_concurrency_limit
553 | # parameter. The default is $default_destination_concurrency_limit for
554 | # most delivery transports. For the local delivery agent the default is 2.
555 |
556 | #local_destination_concurrency_limit = 2
557 | #default_destination_concurrency_limit = 20
558 |
559 | # DEBUGGING CONTROL
560 | #
561 | # The debug_peer_level parameter specifies the increment in verbose
562 | # logging level when an SMTP client or server host name or address
563 | # matches a pattern in the debug_peer_list parameter.
564 | #
565 | debug_peer_level = 2
566 |
567 | # The debug_peer_list parameter specifies an optional list of domain
568 | # or network patterns, /file/name patterns or type:name tables. When
569 | # an SMTP client or server host name or address matches a pattern,
570 | # increase the verbose logging level by the amount specified in the
571 | # debug_peer_level parameter.
572 | #
573 | #debug_peer_list = 127.0.0.1
574 | #debug_peer_list = some.domain
575 |
576 | # The debugger_command specifies the external command that is executed
577 | # when a Postfix daemon program is run with the -D option.
578 | #
579 | # Use "command .. & sleep 5" so that the debugger can attach before
580 | # the process marches on. If you use an X-based debugger, be sure to
581 | # set up your XAUTHORITY environment variable before starting Postfix.
582 | #
583 | debugger_command =
584 | PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
585 | xxgdb $daemon_directory/$process_name $process_id & sleep 5
586 |
587 | # If you can't use X, use this to capture the call stack when a
588 | # daemon crashes. The result is in a file in the configuration
589 | # directory, and is named after the process name and the process ID.
590 | #
591 | # debugger_command =
592 | # PATH=/bin:/usr/bin:/usr/local/bin; export PATH; (echo cont;
593 | # echo where) | gdb $daemon_directory/$process_name $process_id 2>&1
594 | # >$config_directory/$process_name.$process_id.log & sleep 5
595 | #
596 | # Another possibility is to run gdb under a detached screen session.
597 | # To attach to the screen sesssion, su root and run "screen -r
598 | # " where uniquely matches one of the detached
599 | # sessions (from "screen -list").
600 | #
601 | # debugger_command =
602 | # PATH=/bin:/usr/bin:/sbin:/usr/sbin; export PATH; screen
603 | # -dmS $process_name gdb $daemon_directory/$process_name
604 | # $process_id & sleep 1
605 |
606 | # INSTALL-TIME CONFIGURATION INFORMATION
607 | #
608 | # The following parameters are used when installing a new Postfix version.
609 | #
610 | # sendmail_path: The full pathname of the Postfix sendmail command.
611 | # This is the Sendmail-compatible mail posting interface.
612 | #
613 | sendmail_path =
614 |
615 | # newaliases_path: The full pathname of the Postfix newaliases command.
616 | # This is the Sendmail-compatible command to build alias databases.
617 | #
618 | newaliases_path =
619 |
620 | # mailq_path: The full pathname of the Postfix mailq command. This
621 | # is the Sendmail-compatible mail queue listing command.
622 | #
623 | mailq_path =
624 |
625 | # setgid_group: The group for mail submission and queue management
626 | # commands. This must be a group name with a numerical group ID that
627 | # is not shared with other accounts, not even with the Postfix account.
628 | #
629 | setgid_group =
630 |
631 | # html_directory: The location of the Postfix HTML documentation.
632 | #
633 | html_directory =
634 |
635 | # manpage_directory: The location of the Postfix on-line manual pages.
636 | #
637 | manpage_directory =
638 |
639 | # sample_directory: The location of the Postfix sample configuration files.
640 | # This parameter is obsolete as of Postfix 2.1.
641 | #
642 | sample_directory =
643 |
644 | # readme_directory: The location of the Postfix README files.
645 | #
646 | readme_directory =
647 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/main.cf.default.json:
--------------------------------------------------------------------------------
1 | {
2 | "MultiLineValues": [
3 | "AllowEmptyTopSection"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/mysqld.cnf:
--------------------------------------------------------------------------------
1 | [mysqld]
2 | user = mysql
3 | pid-file = /var/run/mysqld/mysqld.pid
4 | skip-external-locking
5 | old_passwords = 1
6 | skip-bdb
7 | # we don't need ACID today
8 | skip-innodb
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/mysqld.cnf.json:
--------------------------------------------------------------------------------
1 | {
2 | "MultiLineValues": [
3 | "AllowValuelessKeys"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/openssl.cnf:
--------------------------------------------------------------------------------
1 | #
2 | # OpenSSL example configuration file.
3 | # This is mostly being used for generation of certificate requests.
4 | #
5 |
6 | # This definition stops the following lines choking if HOME isn't
7 | # defined.
8 | HOME = .
9 | RANDFILE = $ENV::HOME/.rnd
10 |
11 | # Extra OBJECT IDENTIFIER info:
12 | #oid_file = $ENV::HOME/.oid
13 | oid_section = new_oids
14 |
15 | # To use this configuration file with the "-extfile" option of the
16 | # "openssl x509" utility, name here the section containing the
17 | # X.509v3 extensions to use:
18 | # extensions =
19 | # (Alternatively, use a configuration file that has only
20 | # X.509v3 extensions in its main [= default] section.)
21 |
22 | [ new_oids ]
23 |
24 | # We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
25 | # Add a simple OID like this:
26 | # testoid1=1.2.3.4
27 | # Or use config file substitution like this:
28 | # testoid2=${testoid1}.5.6
29 |
30 | # Policies used by the TSA examples.
31 | tsa_policy1 = 1.2.3.4.1
32 | tsa_policy2 = 1.2.3.4.5.6
33 | tsa_policy3 = 1.2.3.4.5.7
34 |
35 | ####################################################################
36 | [ ca ]
37 | default_ca = CA_default # The default ca section
38 |
39 | ####################################################################
40 | [ CA_default ]
41 |
42 | dir = ./demoCA # Where everything is kept
43 | certs = $dir/certs # Where the issued certs are kept
44 | crl_dir = $dir/crl # Where the issued crl are kept
45 | database = $dir/index.txt # database index file.
46 | #unique_subject = no # Set to 'no' to allow creation of
47 | # several ctificates with same subject.
48 | new_certs_dir = $dir/newcerts # default place for new certs.
49 |
50 | certificate = $dir/cacert.pem # The CA certificate
51 | serial = $dir/serial # The current serial number
52 | crlnumber = $dir/crlnumber # the current crl number
53 | # must be commented out to leave a V1 CRL
54 | crl = $dir/crl.pem # The current CRL
55 | private_key = $dir/private/cakey.pem# The private key
56 | RANDFILE = $dir/private/.rand # private random number file
57 |
58 | x509_extensions = usr_cert # The extentions to add to the cert
59 |
60 | # Comment out the following two lines for the "traditional"
61 | # (and highly broken) format.
62 | name_opt = ca_default # Subject Name options
63 | cert_opt = ca_default # Certificate field options
64 |
65 | # Extension copying option: use with caution.
66 | # copy_extensions = copy
67 |
68 | # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
69 | # so this is commented out by default to leave a V1 CRL.
70 | # crlnumber must also be commented out to leave a V1 CRL.
71 | # crl_extensions = crl_ext
72 |
73 | default_days = 365 # how long to certify for
74 | default_crl_days= 30 # how long before next CRL
75 | default_md = default # use public key default MD
76 | preserve = no # keep passed DN ordering
77 |
78 | # A few difference way of specifying how similar the request should look
79 | # For type CA, the listed attributes must be the same, and the optional
80 | # and supplied fields are just that :-)
81 | policy = policy_match
82 |
83 | # For the CA policy
84 | [ policy_match ]
85 | countryName = match
86 | stateOrProvinceName = match
87 | organizationName = match
88 | organizationalUnitName = optional
89 | commonName = supplied
90 | emailAddress = optional
91 |
92 | # For the 'anything' policy
93 | # At this point in time, you must list all acceptable 'object'
94 | # types.
95 | [ policy_anything ]
96 | countryName = optional
97 | stateOrProvinceName = optional
98 | localityName = optional
99 | organizationName = optional
100 | organizationalUnitName = optional
101 | commonName = supplied
102 | emailAddress = optional
103 |
104 | ####################################################################
105 | [ req ]
106 | default_bits = 2048
107 | default_keyfile = privkey.pem
108 | distinguished_name = req_distinguished_name
109 | attributes = req_attributes
110 | x509_extensions = v3_ca # The extentions to add to the self signed cert
111 |
112 | # Passwords for private keys if not present they will be prompted for
113 | # input_password = secret
114 | # output_password = secret
115 |
116 | # This sets a mask for permitted string types. There are several options.
117 | # default: PrintableString, T61String, BMPString.
118 | # pkix : PrintableString, BMPString (PKIX recommendation before 2004)
119 | # utf8only: only UTF8Strings (PKIX recommendation after 2004).
120 | # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
121 | # MASK:XXXX a literal mask value.
122 | # WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
123 | string_mask = utf8only
124 |
125 | # req_extensions = v3_req # The extensions to add to a certificate request
126 |
127 | [ req_distinguished_name ]
128 | countryName = Country Name (2 letter code)
129 | countryName_default = AU
130 | countryName_min = 2
131 | countryName_max = 2
132 |
133 | stateOrProvinceName = State or Province Name (full name)
134 | stateOrProvinceName_default = Some-State
135 |
136 | localityName = Locality Name (eg, city)
137 |
138 | 0.organizationName = Organization Name (eg, company)
139 | 0.organizationName_default = Internet Widgits Pty Ltd
140 |
141 | # we can do this but it is not needed normally :-)
142 | #1.organizationName = Second Organization Name (eg, company)
143 | #1.organizationName_default = World Wide Web Pty Ltd
144 |
145 | organizationalUnitName = Organizational Unit Name (eg, section)
146 | #organizationalUnitName_default =
147 |
148 | commonName = Common Name (e.g. server FQDN or YOUR name)
149 | commonName_max = 64
150 |
151 | emailAddress = Email Address
152 | emailAddress_max = 64
153 |
154 | # SET-ex3 = SET extension number 3
155 |
156 | [ req_attributes ]
157 | challengePassword = A challenge password
158 | challengePassword_min = 4
159 | challengePassword_max = 20
160 |
161 | unstructuredName = An optional company name
162 |
163 | [ usr_cert ]
164 |
165 | # These extensions are added when 'ca' signs a request.
166 |
167 | # This goes against PKIX guidelines but some CAs do it and some software
168 | # requires this to avoid interpreting an end user certificate as a CA.
169 |
170 | basicConstraints=CA:FALSE
171 |
172 | # Here are some examples of the usage of nsCertType. If it is omitted
173 | # the certificate can be used for anything *except* object signing.
174 |
175 | # This is OK for an SSL server.
176 | # nsCertType = server
177 |
178 | # For an object signing certificate this would be used.
179 | # nsCertType = objsign
180 |
181 | # For normal client use this is typical
182 | # nsCertType = client, email
183 |
184 | # and for everything including object signing:
185 | # nsCertType = client, email, objsign
186 |
187 | # This is typical in keyUsage for a client certificate.
188 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
189 |
190 | # This will be displayed in Netscape's comment listbox.
191 | nsComment = "OpenSSL Generated Certificate"
192 |
193 | # PKIX recommendations harmless if included in all certificates.
194 | subjectKeyIdentifier=hash
195 | authorityKeyIdentifier=keyid,issuer
196 |
197 | # This stuff is for subjectAltName and issuerAltname.
198 | # Import the email address.
199 | # subjectAltName=email:copy
200 | # An alternative to produce certificates that aren't
201 | # deprecated according to PKIX.
202 | # subjectAltName=email:move
203 |
204 | # Copy subject details
205 | # issuerAltName=issuer:copy
206 |
207 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
208 | #nsBaseUrl
209 | #nsRevocationUrl
210 | #nsRenewalUrl
211 | #nsCaPolicyUrl
212 | #nsSslServerName
213 |
214 | # This is required for TSA certificates.
215 | # extendedKeyUsage = critical,timeStamping
216 |
217 | [ v3_req ]
218 |
219 | # Extensions to add to a certificate request
220 |
221 | basicConstraints = CA:FALSE
222 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment
223 |
224 | [ v3_ca ]
225 |
226 |
227 | # Extensions for a typical CA
228 |
229 |
230 | # PKIX recommendation.
231 |
232 | subjectKeyIdentifier=hash
233 |
234 | authorityKeyIdentifier=keyid:always,issuer
235 |
236 | # This is what PKIX recommends but some broken software chokes on critical
237 | # extensions.
238 | #basicConstraints = critical,CA:true
239 | # So we do this instead.
240 | basicConstraints = CA:true
241 |
242 | # Key usage: this is typical for a CA certificate. However since it will
243 | # prevent it being used as an test self-signed certificate it is best
244 | # left out by default.
245 | # keyUsage = cRLSign, keyCertSign
246 |
247 | # Some might want this also
248 | # nsCertType = sslCA, emailCA
249 |
250 | # Include email address in subject alt name: another PKIX recommendation
251 | # subjectAltName=email:copy
252 | # Copy issuer details
253 | # issuerAltName=issuer:copy
254 |
255 | # DER hex encoding of an extension: beware experts only!
256 | # obj=DER:02:03
257 | # Where 'obj' is a standard or added object
258 | # You can even override a supported extension:
259 | # basicConstraints= critical, DER:30:03:01:01:FF
260 |
261 | [ crl_ext ]
262 |
263 | # CRL extensions.
264 | # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
265 |
266 | # issuerAltName=issuer:copy
267 | authorityKeyIdentifier=keyid:always
268 |
269 | [ proxy_cert_ext ]
270 | # These extensions should be added when creating a proxy certificate
271 |
272 | # This goes against PKIX guidelines but some CAs do it and some software
273 | # requires this to avoid interpreting an end user certificate as a CA.
274 |
275 | basicConstraints=CA:FALSE
276 |
277 | # Here are some examples of the usage of nsCertType. If it is omitted
278 | # the certificate can be used for anything *except* object signing.
279 |
280 | # This is OK for an SSL server.
281 | # nsCertType = server
282 |
283 | # For an object signing certificate this would be used.
284 | # nsCertType = objsign
285 |
286 | # For normal client use this is typical
287 | # nsCertType = client, email
288 |
289 | # and for everything including object signing:
290 | # nsCertType = client, email, objsign
291 |
292 | # This is typical in keyUsage for a client certificate.
293 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
294 |
295 | # This will be displayed in Netscape's comment listbox.
296 | nsComment = "OpenSSL Generated Certificate"
297 |
298 | # PKIX recommendations harmless if included in all certificates.
299 | subjectKeyIdentifier=hash
300 | authorityKeyIdentifier=keyid,issuer
301 |
302 | # This stuff is for subjectAltName and issuerAltname.
303 | # Import the email address.
304 | # subjectAltName=email:copy
305 | # An alternative to produce certificates that aren't
306 | # deprecated according to PKIX.
307 | # subjectAltName=email:move
308 |
309 | # Copy subject details
310 | # issuerAltName=issuer:copy
311 |
312 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
313 | #nsBaseUrl
314 | #nsRevocationUrl
315 | #nsRenewalUrl
316 | #nsCaPolicyUrl
317 | #nsSslServerName
318 |
319 | # This really needs to be in place for it to be a proxy certificate.
320 | proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
321 |
322 | ####################################################################
323 | [ tsa ]
324 |
325 | default_tsa = tsa_config1 # the default TSA section
326 |
327 | [ tsa_config1 ]
328 |
329 | # These are used by the TSA reply generation only.
330 | dir = ./demoCA # TSA root directory
331 | serial = $dir/tsaserial # The current serial number (mandatory)
332 | crypto_device = builtin # OpenSSL engine to use for signing
333 | signer_cert = $dir/tsacert.pem # The TSA signing certificate
334 | # (optional)
335 | certs = $dir/cacert.pem # Certificate chain to include in reply
336 | # (optional)
337 | signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
338 |
339 | default_policy = tsa_policy1 # Policy if request did not specify it
340 | # (optional)
341 | other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
342 | digests = md5, sha1 # Acceptable message digests (mandatory)
343 | accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
344 | clock_precision_digits = 0 # number of digits after dot. (optional)
345 | ordering = yes # Is ordering defined for timestamps?
346 | # (optional, default: no)
347 | tsa_name = yes # Must the TSA name be included in the reply?
348 | # (optional, default: no)
349 | ess_cert_id_chain = no # Must the ESS cert id chain be included?
350 | # (optional, default: no)
351 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/openssl.cnf.json:
--------------------------------------------------------------------------------
1 | {
2 | "MultiLineValues": [
3 | "AllowEmptyTopSection"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/redis.conf:
--------------------------------------------------------------------------------
1 | bind 11.1.1.11
2 | port 12345
3 | protected-mode no
4 | daemonize yes
5 | supervised no
6 | loglevel notice
7 | databases 16
8 |
9 | tcp-backlog 16000
10 | timeout 0
11 | tcp-keepalive 60
12 | maxclients 16000
13 |
14 | maxmemory 6144MB
15 | maxmemory-policy volatile-lru
16 | save 300 10
17 |
18 | stop-writes-on-bgsave-error no
19 | rdbcompression yes
20 | rdbchecksum yes
21 |
22 | slave-serve-stale-data yes
23 | slave-read-only yes
24 | slave-priority 100
25 | repl-ping-slave-period 10
26 | repl-disable-tcp-nodelay no
27 | min-slaves-to-write 0
28 | min-slaves-max-lag 0
29 |
30 | appendonly no
31 | appendfsync everysec
32 | aof-rewrite-incremental-fsync yes
33 | auto-aof-rewrite-percentage 100
34 | auto-aof-rewrite-min-size 64mb
35 | no-appendfsync-on-rewrite no
36 |
37 | hash-max-ziplist-entries 512
38 | hash-max-ziplist-value 64
39 |
40 | list-max-ziplist-entries 512
41 | list-max-ziplist-value 64
42 |
43 | set-max-intset-entries 512
44 |
45 | zset-max-ziplist-entries 128
46 | zset-max-ziplist-value 64
47 | activerehashing yes
48 | client-output-buffer-limit normal 0 0 0
49 | client-output-buffer-limit slave 512mb 128mb 120
50 | client-output-buffer-limit pubsub 32mb 8mb 60
51 |
52 | cluster-enabled yes
53 | cluster-node-timeout 30000
54 | cluster-slave-validity-factor 10
55 | cluster-migration-barrier 1
56 | cluster-require-full-coverage yes
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/redis.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "KeyValueSeparator": " ",
3 | "MultiLineValues": [
4 | "AllowValuelessKeys",
5 | "AllowEmptyTopSection"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/skinr.help.ini:
--------------------------------------------------------------------------------
1 | [overview]
2 | title = "Overview"
3 | weight = 0
4 |
5 | [syntax]
6 | title = "Syntax"
7 | weight = 1
8 |
9 | [css-js]
10 | title = "CSS, Stylesheets & JavaScript"
11 | parent = syntax
12 | weight = 1
13 |
14 | [features]
15 | title = "Features"
16 | parent = syntax
17 | weight = 2
18 |
19 | [templates]
20 | title = "Templates"
21 | parent = syntax
22 | weight = 5
23 |
24 | [examples]
25 | title = "Examples"
26 | parent = syntax
27 | weight = 6
28 |
29 | # test comment
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/wakatime.cfg:
--------------------------------------------------------------------------------
1 | [settings]
2 | api_key=00000000-0000-0000-0000-000000000000
3 | proxy=
4 | debug=false
5 | exclude=
6 | ^/var/
7 | ^/tmp/
8 | ^/private/
9 | COMMIT_EDITMSG$
10 | PULLREQ_EDITMSG$
11 | MERGE_MSG$
12 |
13 | [projectmap]
14 | Projects/Web/Customer/YRT/(.*)/=YRT
15 | Projects/Web/Customer/SEL/(.*)/=SEL
16 | Projects/Web/Customer/EX/example.com(.*)/=Example
17 | Projects/Web/Customer/EX/attribution.example.com/(.*)/=EXP survey
18 | AnotherCustomer.Configurator.(.*) = Configurator
19 | AnotherCustomer.App.Publisher = Publisher
20 |
--------------------------------------------------------------------------------
/tests/Resources/RealWorld/wakatime.cfg.json:
--------------------------------------------------------------------------------
1 | {
2 | "MultiLineValues": [
3 | "Simple"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Resources/Structure/from-scratch.conf:
--------------------------------------------------------------------------------
1 | [section1]
2 | string=value
3 |
4 | [section2]
5 | bool=true
6 |
7 | [section3]
8 | doble=0.2
--------------------------------------------------------------------------------
/tests/Resources/Structure/indented.ini:
--------------------------------------------------------------------------------
1 | [Sections Can Be Indented]
2 | can_values_be_as_well = True
3 | does_that_mean_anything_special = False
4 | purpose = formatting for readability
5 | multiline_values = are
6 | handled just fine as
7 | long as they are indented
8 | deeper than the first line
9 | of a value
10 |
11 | # Did I mention we can indent comments, too?
--------------------------------------------------------------------------------
/tests/Resources/Structure/interpolation.conf:
--------------------------------------------------------------------------------
1 | [Paths]
2 | home_dir: /Users
3 | my_dir: ${home_dir}/lumberjack
4 | my_pictures: ${my_dir}/Pictures
5 |
6 | [Common]
7 | home_dir: /Users
8 | library_dir: /Library
9 | system_dir: /System
10 | macports_dir: /opt/local
11 |
12 | [Frameworks]
13 | Python: 3.2
14 | path: ${Common:system_dir}/Library/Frameworks/
15 |
16 | [Arthur]
17 | nickname: Two Sheds
18 | last_name: Jackson
19 | my_dir: ${Common:home_dir}/twosheds
20 | my_pictures: ${my_dir}/Pictures
21 | python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}
--------------------------------------------------------------------------------
/tests/Resources/Structure/multi-line-delimited.ini:
--------------------------------------------------------------------------------
1 | [Multiline Values]
2 | chorus="I'm a lumberjack, and I'm okay
3 | I sleep all night and I work all day
4 | "
--------------------------------------------------------------------------------
/tests/Resources/Structure/multi-line.ini:
--------------------------------------------------------------------------------
1 | [Multiline Values]
2 | chorus=I'm a lumberjack, and I'm okay
3 | I sleep all night and I work all day
--------------------------------------------------------------------------------
/tests/Resources/Structure/only-comments.ini:
--------------------------------------------------------------------------------
1 | [You can use comments]
2 | # like this
3 | ; or this
4 |
5 | # By default only in an empty line.
6 | # Inline comments can be harmful because they prevent users
7 | # from using the delimiting characters as parts of values.
8 | # That being said, this can be customized.
9 |
--------------------------------------------------------------------------------
/tests/Resources/Structure/simple-keys.ini:
--------------------------------------------------------------------------------
1 | [Simple Values]
2 | key=value
3 | spaces in keys=allowed
4 | spaces in values=allowed as well
5 | spaces around the delimiter = obviously
--------------------------------------------------------------------------------
/tests/Resources/Values/array.cnf:
--------------------------------------------------------------------------------
1 | [settings]
2 | exclude =
3 | ^/var/
4 | ^/tmp/
5 | ^/private/
6 | COMMIT_EDITMSG$
7 | PULLREQ_EDITMSG$
8 | MERGE_MSG$
--------------------------------------------------------------------------------
/tests/Resources/Values/boolean.ini:
--------------------------------------------------------------------------------
1 | [Simple]
2 | empty=
3 | numericTrue=1
4 | numericFalse=0
5 | textTrue = true
6 | textFalse = false
7 |
8 | [YesNo]
9 | sampleYes=Yes
10 | sampleNo=no
11 |
12 | [OnOff]
13 | sampleOn=on
14 | sampleOff=Off
15 |
16 | [EnabledDisabled]
17 | sampleOn=Enabled
18 | sampleOff=disabled
19 |
20 | [ValoriItaliani]
21 | positivo = vero
22 | sampleOff = falso
23 |
--------------------------------------------------------------------------------
/tests/Resources/Values/double.conf:
--------------------------------------------------------------------------------
1 | [Works]
2 | empty=
3 | integer=1
4 | usual=0.000001
5 | withD=0.6D
6 | engineeringNotation = 1.7E+3
7 | float = 4.5f
8 | thousands=1,000
9 | dollars=$2,999
10 |
11 | [ItalianLocalized]
12 | withComa = 9,3
13 |
14 | [DoesntWork]
15 | random = sdgfery56d
16 |
--------------------------------------------------------------------------------