Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Core/NetArgumentParser/Argument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace NetArgumentParser;

public class Argument
{
private const StringComparison _defaultStringComparison = StringComparison.CurrentCulture;
private const StringComparison _defaultStringComparison = StringComparison.Ordinal;

public Argument(string argument, bool recognizeSlashAsOption = false)
{
Expand Down
4 changes: 2 additions & 2 deletions Core/NetArgumentParser/DefaultExceptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,13 @@ private static void ThrowLessEqual<T>(T value, T other, string? paramName)

private static void ThrowEqual<T>(T value, T other, string? paramName)
{
string message = $"{paramName} ('{value}') must be equal to {other}.";
string message = $"{paramName} ('{value}') must not be equal to {other}.";
throw new ArgumentOutOfRangeException(paramName, value, message);
}

private static void ThrowNotEqual<T>(T value, T other, string? paramName)
{
string message = $"{paramName} ('{value}') must not be equal to {other}.";
string message = $"{paramName} ('{value}') must be equal to {other}.";
throw new ArgumentOutOfRangeException(paramName, value, message);
}
}
76 changes: 65 additions & 11 deletions Core/NetArgumentParser/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NetArgumentParser.Extensions;

internal static class StringExtensions
{
private const StringComparison _defaultComparisonType = StringComparison.Ordinal;

#if !NET5_0_OR_GREATER && !NETCOREAPP3_0_OR_GREATER && !NETSTANDARD2_1_OR_GREATER
private const StringComparison _defaultComparisonType = StringComparison.CurrentCulture;
internal static string Replace(
this string text,
string oldValue,
string? newValue,
StringComparison comparisonType = _defaultComparisonType)
{
ExtendedArgumentNullException.ThrowIfNull(text, nameof(text));
ExtendedArgumentException.ThrowIfNullOrEmpty(oldValue, nameof(oldValue));

string replacement = newValue ?? string.Empty;

int currentPosition = 0;
int matchIndex = text.IndexOf(oldValue, currentPosition, comparisonType);

if (matchIndex < 0)
return text;

var builder = new StringBuilder(text.Length);

while (matchIndex >= 0)
{
_ = builder
.Append(text, currentPosition, matchIndex - currentPosition)
.Append(replacement);

currentPosition = matchIndex + oldValue.Length;
matchIndex = text.IndexOf(oldValue, currentPosition, comparisonType);
}

return builder
.Append(text, currentPosition, text.Length - currentPosition)
.ToString();
}

#pragma warning disable IDE0060 // Remove unused parameter
internal static bool Contains(
this string text,
char value,
StringComparison comparisonType = _defaultComparisonType)
{
return text.Contains($"{value}", comparisonType);
}

internal static bool Contains(
this string text,
string? value,
StringComparison comparisonType = _defaultComparisonType)
{
ExtendedArgumentNullException.ThrowIfNull(text, nameof(text));

return value is not null
? text.IndexOf(value, comparisonType) >= 0
: false;
}

internal static int IndexOf(
this string text,
char value,
StringComparison comparisonType = _defaultComparisonType)
{
ExtendedArgumentNullException.ThrowIfNull(text, nameof(text));
return text.Contains($"{value}");
return text.IndexOf($"{value}", comparisonType);
}
#pragma warning restore IDE0060 // Remove unused parameter
#endif

internal static bool StartsWith(
this string text,
Expand All @@ -29,27 +81,29 @@ internal static bool StartsWith(
return text.StartsWith($"{value}", comparisonType);
}

internal static int IndexOf(
internal static bool EndsWith(
this string text,
char value,
StringComparison comparisonType = _defaultComparisonType)
{
ExtendedArgumentNullException.ThrowIfNull(text, nameof(text));
return text.IndexOf($"{value}", comparisonType);
return text.EndsWith($"{value}", comparisonType);
}
#endif

internal static string RemoveLineBreakFromEnd(this string text)
{
ExtendedArgumentNullException.ThrowIfNull(text, nameof(text));
return RemoveLineBreakFromEnd(text, Environment.NewLine);
}

internal static string RemoveLineBreakFromEnd(this string text, string lineBreak)
internal static string RemoveLineBreakFromEnd(
this string text,
string lineBreak,
StringComparison comparisonType = _defaultComparisonType)
{
ExtendedArgumentNullException.ThrowIfNull(text, nameof(text));

while (text.EndsWith(lineBreak, StringComparison.CurrentCulture))
while (text.EndsWith(lineBreak, comparisonType))
{
int lineBreakLength = lineBreak.Length;
text = text.Remove(text.Length - lineBreakLength);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ private static bool TryParseLogicalOperator(string data, out LogicalOperator log
{
ExtendedArgumentException.ThrowIfNullOrWhiteSpace(data, nameof(data));

LogicalOperator? result = data.ToUpper(CultureInfo.CurrentCulture) switch
LogicalOperator? result = data.ToUpperInvariant() switch
{
"AND" or "&&" or "&" => LogicalOperator.And,
"OR" or "||" or "|" => LogicalOperator.Or,
Expand All @@ -172,7 +172,7 @@ private static Predicate<T> ParseComparePredicate<T>(
ExtendedArgumentNullException.ThrowIfNull(parameters, nameof(parameters));
DefaultExceptions.ThrowIfNotEqual(parameters.Length, 1, nameof(parameters.Length));

double rhs = double.Parse(parameters[0], CultureInfo.CurrentCulture);
double rhs = double.Parse(parameters[0], CultureInfo.InvariantCulture);
return value => value is null || compareFunc(value, rhs);
}

Expand Down Expand Up @@ -217,8 +217,8 @@ private static Predicate<T> ParseInRangePredicate<T>(string[] parameters)
ExtendedArgumentNullException.ThrowIfNull(parameters, nameof(parameters));
DefaultExceptions.ThrowIfNotEqual(parameters.Length, 2, nameof(parameters.Length));

dynamic minValue = double.Parse(parameters[0], CultureInfo.CurrentCulture);
dynamic maxValue = double.Parse(parameters[1], CultureInfo.CurrentCulture);
dynamic minValue = double.Parse(parameters[0], CultureInfo.InvariantCulture);
dynamic maxValue = double.Parse(parameters[1], CultureInfo.InvariantCulture);

return value => value is null || (value >= minValue && value <= maxValue);
}
Expand Down Expand Up @@ -294,7 +294,7 @@ private static Predicate<T> ParseMaxFileSizePredicate<T>(string[] parameters)
ExtendedArgumentNullException.ThrowIfNull(parameters, nameof(parameters));
DefaultExceptions.ThrowIfNotEqual(parameters.Length, 1, nameof(parameters.Length));

dynamic maxFileSizeInBytes = long.Parse(parameters[0], CultureInfo.CurrentCulture);
dynamic maxFileSizeInBytes = long.Parse(parameters[0], CultureInfo.InvariantCulture);

return value =>
{
Expand Down Expand Up @@ -324,11 +324,11 @@ private static Predicate<T> ParseFileExtensionPredicate<T>(string[] parameters)
{
const string periodPrefix = ".";

string extension = t.StartsWith(periodPrefix, StringComparison.CurrentCulture)
string extension = t.StartsWith(periodPrefix, StringComparison.Ordinal)
? t
: $"{periodPrefix}{t}";

return extension.ToUpper(CultureInfo.CurrentCulture);
return extension.ToUpperInvariant();
});

return value =>
Expand All @@ -340,7 +340,7 @@ private static Predicate<T> ParseFileExtensionPredicate<T>(string[] parameters)
{
string fileExtension = Path
.GetExtension(filePath)
.ToUpper(CultureInfo.CurrentCulture);
.ToUpperInvariant();

return allowedExtensions.Contains(fileExtension);
}
Expand Down Expand Up @@ -394,7 +394,7 @@ private Predicate<T> ParsePredicate<T>(string[] data)
string name = shouldNegatePredicate ? data[0].Substring(1) : data[0];
string[] parameters = [.. data.Skip(1)];

Predicate<T> predicate = name.ToUpper(CultureInfo.CurrentCulture) switch
Predicate<T> predicate = name.ToUpperInvariant() switch
{
"EQUAL" or "==" or "=" => ParseEqualPredicate<T>(parameters),
"NOTEQUAL" or "!=" or "<>" => ParseNotEqualPredicate<T>(parameters),
Expand Down
2 changes: 1 addition & 1 deletion Core/NetArgumentParser/Options/MultipleValueOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ protected override bool IsValueSatisfyChoices(IList<T> value)

return choices.Any(t =>
{
var stringComparer = new StringEqualityComparer(StringComparison.OrdinalIgnoreCase);
var stringComparer = new StringEqualityComparer(StringComparison.CurrentCultureIgnoreCase);
return enumerableComparer.Invoke(t, castedValue!, stringComparer);
});
}
Expand Down
8 changes: 4 additions & 4 deletions Core/NetArgumentParser/Options/ValueOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ protected string GetDefaultMetaVariable()
string prefferedName = GetPrefferedName();

char[] transformedName = prefferedName
.Select(t => char.IsLetter(t) ? char.ToUpper(t, CultureInfo.CurrentCulture) : '_')
.Select(t => char.IsLetter(t) ? char.ToUpperInvariant(t) : '_')
.ToArray();

return new string(transformedName);
Expand Down Expand Up @@ -393,7 +393,7 @@ protected virtual bool IsValueSatisfyChoices(T value)
if (IgnoreCaseInChoices && typeof(T) == typeof(string))
{
IEnumerable<string> choices = _choices.Cast<string>();
StringEqualityComparer comparer = new(StringComparison.OrdinalIgnoreCase);
StringEqualityComparer comparer = new(StringComparison.CurrentCultureIgnoreCase);

return choices.Contains(value as string, comparer);
}
Expand All @@ -409,8 +409,8 @@ protected virtual bool IsBeforeParseValueSatisfyChoices(string value)
return true;

StringComparison stringComparison = IgnoreCaseInChoices
? StringComparison.OrdinalIgnoreCase
: StringComparison.Ordinal;
? StringComparison.CurrentCultureIgnoreCase
: StringComparison.CurrentCulture;

var comparer = new StringEqualityComparer(stringComparison);

Expand Down
8 changes: 4 additions & 4 deletions Documentation/ConnectProject.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Let's consider this step-by-step instructions for creating a sample project and
```
cd ~/Repos
```
- Step 2: Create folder for your project and go to it.
- Step 2: Create folder for your project and move to it.
```
mkdir MyProject && cd MyProject
```
Expand All @@ -48,15 +48,15 @@ mkdir Vendor && cd Vendor
```
git clone https://github.com/yakovypg/NetArgumentParser.git
```
- Step 8: Go back to the root folder.
- Step 8: Move back to the root folder.
```
cd ..
```
- Step 9: Add **NetArgumentParser** to the solution.
```
dotnet sln add Vendor/NetArgumentParser/Core/NetArgumentParser
```
- Step 10: Go to your project folder.
- Step 10: Move to your project folder.
```
cd MyProject
```
Expand Down Expand Up @@ -91,4 +91,4 @@ dotnet build -c Release
- Step 14: Run the created application.
```
dotnet run --angle 45 A
```
```
2 changes: 1 addition & 1 deletion Examples/NetArgumentParser.Examples.AllUseCases/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

var nameOption = new ValueOption<string>("name", "n", afterValueParsingAction: t => resultValues.Name = t)
{
Converter = new ValueConverter<string>(t => t.ToUpper(CultureInfo.CurrentCulture))
Converter = new ValueConverter<string>(t => t.ToUpperInvariant())
};

var nickOption = new ValueOption<string>("nick", afterValueParsingAction: t => resultValues.Name = t);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using System;
using System.Globalization;
using NetArgumentParser;
using NetArgumentParser.Converters;
using NetArgumentParser.Options;

var toUpperStringConverter = new ValueConverter<string>(
t => t.ToUpper(CultureInfo.CurrentCulture));
t => t.ToUpperInvariant());

var toLowerStringConverter = new ValueConverter<string>(
t => t.ToLower(CultureInfo.CurrentCulture));
t => t.ToUpperInvariant());

string firstName = string.Empty;
string secondName = string.Empty;
Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</p>

## About
**NetArgumentParser** is a cross-platform, free and open source library for parsing command-line options, arguments and subcommands. This library contains the main features of popular argument parsers such as `argparse`, as well as many of its own.
**NetArgumentParser** is a cross-platform, free, open source library for parsing command-line options, arguments and subcommands. This library contains the main features of popular argument parsers such as `argparse`, as well as many of its own.

**NetArgumentParser** supports many frameworks, so you can use it in most of your projects. Moreover, you can find clear examples of using this library [here](Examples).

Expand All @@ -23,8 +23,8 @@
## Table of contents
* [Main Features](#main-features)
* [Quick Start](#quick-start)
* [Build Project](#build-project)
* [Test Project](#test-project)
* [Build From Source](#build-from-source)
* [Run Tests](#run-tests)
* [Connect Project](#connect-project)
* [Documentation](#documentation)
* [Development](#development)
Expand All @@ -49,15 +49,15 @@ Many other features with examples you can find in [documentation](#documentation
## Quick Start
To start working with the library you need to [connect](#connect-project) it to your project. If you are going to connect a library cloned from a repository, you may want to [build](#build-project) and [test](#test-project) it before doing so.

### Build Project
You can [build](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build) the library with the following command, which should be run from the root of the library project.
```
### Build From Source
To [build](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build) the library, run the following command from the project root.
```bash
dotnet build
```

### Test Project
You can [test](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test) the library with the following command, which should be run from the root of the library project.
```
### Run Tests
To [test](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test) the library, run the following command from the project root.
```bash
dotnet test
```

Expand Down
Loading
Loading