Skip to content

Commit

Permalink
Merge pull request #60 from rogusdev/allow-special-chars-in-identifiers
Browse files Browse the repository at this point in the history
Allow dash and period in env var identifiers
  • Loading branch information
rogusdev authored Sep 18, 2021
2 parents c906d24 + f30c5f0 commit 6a7bb3c
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
13 changes: 6 additions & 7 deletions src/DotNetEnv/Parsers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,12 @@ from _ in Backslash
from c in Parse.AnyChar
select ToEscapeChar(c);

//public static readonly Parser<string> Identifier = Parse.RegexMatch(@"[a-zA-Z_][a-zA-Z_0-9]*").Token();
// https://github.com/sprache/Sprache/blob/c8a3b0c5d06dcf5f0d8d4e0087cd8a628aa6549c/samples/XmlExample/Program.cs#L52
// I am not clear why that uses XOr instead of just Or, which seems more accurate and cheaper
// maybe should be using https://github.com/sprache/Sprache/blob/c8a3b0c5d06dcf5f0d8d4e0087cd8a628aa6549c/src/Sprache/Parse.Primitives.cs#L26
// officially *nix env vars can only be /[a-zA-Z_][a-zA-Z_0-9]*/
// but because technically you can set env vars that are basically anything except equals signs, allow some flexibility
private static readonly Parser<char> IdentifierSpecialChars = Parse.Chars(".-");
internal static readonly Parser<string> Identifier =
from head in Parse.Letter.Or(Underscore)
from tail in Parse.LetterOrDigit.Or(Underscore).Many().Text()
from tail in Parse.LetterOrDigit.Or(Underscore).Or(IdentifierSpecialChars).Many().Text()
select head + tail;

private static byte ToOctalByte (string value)
Expand Down Expand Up @@ -188,7 +187,7 @@ from d in DollarSign

// double quoted values can have everything: interpolated variables,
// plus whitespace, escaped chars, and byte code chars
internal static Parser<ValueCalculator> DoubleQuotedValueContents =
internal static readonly Parser<ValueCalculator> DoubleQuotedValueContents =
InterpolatedValue.Or(
SpecialChar
.Or(NotControlNorWhitespace("\"\\$"))
Expand All @@ -201,7 +200,7 @@ from d in DollarSign
// but no interpolation, no escaped chars, no byte code chars
// notably no single quotes inside either -- no escaping!
// single quotes are for when you want truly raw values
internal static Parser<ValueCalculator> SingleQuotedValueContents =
internal static readonly Parser<ValueCalculator> SingleQuotedValueContents =
NotControlNorWhitespace("'")
.Or(Parse.WhiteSpace.AtLeastOnce().Text())
.AtLeastOnce()
Expand Down
9 changes: 9 additions & 0 deletions test/DotNetEnv.Tests/ParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,17 @@ public void ParseIdentifier ()
Assert.Equal("_n", Parsers.Identifier.End().Parse("_n"));
Assert.Equal("__", Parsers.Identifier.End().Parse("__"));
Assert.Equal("_0", Parsers.Identifier.End().Parse("_0"));
Assert.Equal("a_b", Parsers.Identifier.End().Parse("a_b"));
Assert.Equal("_a_b", Parsers.Identifier.End().Parse("_a_b"));
Assert.Equal("a.b", Parsers.Identifier.End().Parse("a.b"));
Assert.Equal("a-b", Parsers.Identifier.End().Parse("a-b"));
Assert.Throws<ParseException>(() => Parsers.Identifier.End().Parse("\"name"));
Assert.Throws<ParseException>(() => Parsers.Identifier.End().Parse("0name"));
Assert.Throws<ParseException>(() => Parsers.Identifier.End().Parse(".a.b"));
Assert.Throws<ParseException>(() => Parsers.Identifier.End().Parse("-a.b"));
Assert.Throws<ParseException>(() => Parsers.Identifier.End().Parse("a!b"));
Assert.Throws<ParseException>(() => Parsers.Identifier.End().Parse("a?b"));
Assert.Throws<ParseException>(() => Parsers.Identifier.End().Parse("a*b"));
}

[Fact]
Expand Down

0 comments on commit 6a7bb3c

Please sign in to comment.