Skip to content

Commit 36e8efc

Browse files
committed
Make so that linktime properties parse only booleans
1 parent c8225cc commit 36e8efc

File tree

4 files changed

+29
-141
lines changed

4 files changed

+29
-141
lines changed

README.md

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,8 @@ the dedicated [sbt plugin](https://scala-native.readthedocs.io/en/stable/user/sb
1111
scala-native-cli --help will bring up possible options and syntax.
1212
Since options are dependent on the used version of scala-native-cli, please use it for further instructions.
1313

14-
### Passing link-time resolved properties
15-
16-
Scala Native allows use of link-time properties - values that are used to resolve `if` code blocks on link-time.
17-
Their non-standard format requires special care.
18-
19-
In scala-native-cli their value is defined as follows:
20-
21-
```keystring=[Type]value```
22-
23-
`keystring` is always a string, however value has to have a type specified in the square brackets. It can be one of the following:
24-
25-
* `Short`
26-
* `Int`
27-
* `Long`
28-
* `Float`
29-
* `Double`
30-
* `Char`
31-
* `Boolean`
32-
* `String`
33-
3414
## Logging
3515

3616
For logging purposes, a default Scala Native logger is used. By default it will only show `Error` messages, but its verbosity can be increased with a -v flag.
17+
18+

cli/version_newer/src/main/scala/scala/scalanative/cli/options/NativeConfigOptions.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ case class NativeConfigOptions(
3939
noOptimize: Boolean = false,
4040
@Group("Native Config")
4141
@HelpMessage(
42-
"User defined properties resolved at link-time. Multiple can be defined. Example: \"isCli=[Boolean]true\""
42+
"User defined properties resolved at link-time. Multiple can be defined. Example: \"isCli=true\""
4343
)
44-
@ValueDescription("<keystring=[type]property>")
44+
@ValueDescription("<keystring=boolean>")
4545
ltp: List[String] = List.empty,
4646
@Group("Native Config")
4747
@HelpMessage("Linking options passed to LLVM. Multiple can be defined.")

cli/version_newer/src/main/scala/scala/scalanative/cli/utils/LinktimePropertyParser.scala

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,25 @@ import scala.util.Try
66
object LinktimePropertyParser {
77

88
val ltpPattern = Pattern.compile("(.*?)=(.*)")
9-
val valueTypePattern = Pattern.compile("\\[(.*?)\\](.*)")
109

1110
@inline
1211
def getLtpPatternException(incorrectPattern: String) =
1312
new IllegalArgumentException(
14-
s"""|Link-time resolved properties must be of pattern keystring=[Type]value
15-
|\"${incorrectPattern}\" is incorrect.""".stripMargin
16-
)
17-
@inline
18-
def getLtpTypeException(incorrectType: String) =
19-
new IllegalArgumentException(
20-
s"""|Unrecognised link-time property value type:
21-
|\"${incorrectType}\" is incorrect.""".stripMargin
13+
s"""|Link-time resolved properties must be of pattern keystring=boolean
14+
|\"${incorrectPattern}\" is incorrect.""".stripMargin
2215
)
2316

2417
def toMap(ltpStrings: List[String]): Either[Throwable, Map[String, Any]] = {
2518
val eitherList =
2619
ltpStrings
2720
.map { inputPattern =>
2821
val matcher = ltpPattern.matcher(inputPattern)
29-
if (!matcher.find() || matcher.groupCount() != 2) {
22+
if (!matcher.find() || matcher.groupCount() != 2 || matcher.group(1).isEmpty()) {
3023
Left(getLtpPatternException(inputPattern))
3124
} else {
32-
val (key, typedValue) = (matcher.group(1), matcher.group(2))
33-
handleTypedValue(inputPattern, typedValue) match {
25+
val (key, booleanString) = (matcher.group(1), matcher.group(2))
26+
27+
Try(booleanString.toBoolean).toEither match {
3428
case Right(value) => Right((key, value))
3529
case Left(value) => Left(value)
3630
}
@@ -50,33 +44,4 @@ object LinktimePropertyParser {
5044
Right(eitherList.collect { case Right(value) => value }.toMap)
5145
}
5246
}
53-
54-
def handleTypedValue(
55-
pattern: String,
56-
typedValue: String
57-
): Either[Throwable, Any] = {
58-
val matcher = valueTypePattern.matcher(typedValue)
59-
60-
if (!matcher.find() || matcher.groupCount() != 2) {
61-
Left(getLtpPatternException(pattern))
62-
} else {
63-
val valueType = matcher.group(1)
64-
val valueContent = matcher.group(2)
65-
66-
Try {
67-
valueType match {
68-
case "Boolean" => valueContent.toBoolean
69-
case "Byte" => valueContent.toByte
70-
case "Char" => valueContent.toInt.toChar
71-
case "Short" => valueContent.toShort
72-
case "Int" => valueContent.toInt
73-
case "Long" => valueContent.toLong
74-
case "Float" => valueContent.toFloat
75-
case "Double" => valueContent.toDouble
76-
case "String" => valueContent
77-
case _ => throw getLtpTypeException(valueType)
78-
}
79-
}.toEither
80-
}
81-
}
8247
}

cli/version_newer/src/test/scala/scala/scalanative/cli/LinktimePropertyParserTest.scala

Lines changed: 19 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -6,97 +6,38 @@ import scala.scalanative.cli.utils.LinktimePropertyParser
66
class LinktimePropertyParserTest extends AnyFlatSpec {
77

88
"LinktimePropertyParser" should "handle boolean value types correctly" in {
9-
val input = List("isTesting=[Boolean]true")
10-
val expected = Map[String, Any]("isTesting" -> true)
9+
val input = List("isTesting=true", "isNotTesting=False")
10+
val expected = Map[String, Any]("isTesting" -> true, "isNotTesting" -> false)
1111
val obtained = LinktimePropertyParser.toMap(input)
1212
assert(obtained.right.get == expected)
1313
}
1414

1515
it should "return error on undefined string patterns" in {
16-
val noEquals = List("key-[String]value")
16+
val noEquals = List("key-true")
1717
val obtainedNoEquals = LinktimePropertyParser.toMap(noEquals)
1818
assert(obtainedNoEquals.isLeft)
1919

20-
val noType = List("key=value")
21-
val obtainedNoType = LinktimePropertyParser.toMap(noEquals)
22-
assert(obtainedNoType.isLeft)
23-
}
24-
25-
it should "handle numeric value types correctly" in {
26-
val input = List(
27-
"testKey0=[Short]1",
28-
"testKey1=[Int]10",
29-
"testKey2=[Long]10000",
30-
"testKey3=[Float]1.20",
31-
"testKey4=[Double]20.20",
32-
"testKey5=[Char]35"
33-
)
34-
val expected = Map[String, Any](
35-
"testKey0" -> 1.asInstanceOf[Short],
36-
"testKey1" -> 10.asInstanceOf[Int],
37-
"testKey2" -> 10000.asInstanceOf[Long],
38-
"testKey3" -> (1.20).asInstanceOf[Float],
39-
"testKey4" -> (20.20).asInstanceOf[Double],
40-
"testKey5" -> 35.asInstanceOf[Char]
41-
)
42-
val obtained = LinktimePropertyParser.toMap(input)
43-
assert(obtained.right.get == expected)
44-
}
45-
46-
it should "handle string value types correctly" in {
47-
val input = List(
48-
"testKey0=[String]1",
49-
"testKey1=[String]windows",
50-
"testKey2=[String]",
51-
"testKey3=[String]with space",
52-
"testKey4=[String]20.20"
53-
)
54-
val expected = Map[String, Any](
55-
"testKey0" -> "1",
56-
"testKey1" -> "windows",
57-
"testKey2" -> "",
58-
"testKey3" -> "with space",
59-
"testKey4" -> "20.20"
60-
)
61-
val obtained = LinktimePropertyParser.toMap(input)
62-
assert(obtained.right.get == expected)
63-
}
64-
65-
it should "fail on unhandled value types" in {
66-
val inputObject = List("testKey=[Object]1")
67-
assert(LinktimePropertyParser.toMap(inputObject).isLeft)
68-
69-
val inputOption = List("testKey=[Option[Int]]Some(1)")
70-
assert(LinktimePropertyParser.toMap(inputOption).isLeft)
20+
val noKey = List("=true")
21+
val obtainedNoKey = LinktimePropertyParser.toMap(noKey)
22+
assert(obtainedNoKey.isLeft)
7123

72-
val inputMessy = List("testKey=[[Int]]1")
73-
assert(LinktimePropertyParser.toMap(inputMessy).isLeft)
24+
val noBoolean = List("key=")
25+
val obtainedNoBoolean = LinktimePropertyParser.toMap(noBoolean)
26+
assert(obtainedNoBoolean.isLeft)
7427
}
7528

76-
it should "fail on incorect value against their defined types" in {
77-
val inputIntString = List("testKey=[Int]stringvalue")
78-
assert(LinktimePropertyParser.toMap(inputIntString).isLeft)
29+
it should "return error on non boolean values" in {
30+
val withString = List("key=string")
31+
val obtainedWithString = LinktimePropertyParser.toMap(withString)
32+
assert(obtainedWithString.isLeft)
7933

80-
val inputBooleanNumber = List("testKey=[Boolean]20")
81-
assert(LinktimePropertyParser.toMap(inputBooleanNumber).isLeft)
34+
val withNull = List("key=null")
35+
val obtainedWithNull = LinktimePropertyParser.toMap(withNull)
36+
assert(obtainedWithNull.isLeft)
8237

83-
val inputDoubleEmpty = List("testKey=[Double]")
84-
assert(LinktimePropertyParser.toMap(inputDoubleEmpty).isLeft)
38+
val withFloat = List("key=1.1")
39+
val obtainedWithFloat = LinktimePropertyParser.toMap(withFloat)
40+
assert(obtainedWithFloat.isLeft)
8541
}
8642

87-
it should "handle square brackets and equals in string value correctly" in {
88-
val inputString = List(
89-
"testKey0=[String]string[]value",
90-
"testKey1=[String][] after brackets",
91-
"testKey2=[String]with=equals"
92-
)
93-
94-
val expected = Map[String, Any](
95-
"testKey0" -> "string[]value",
96-
"testKey1" -> "[] after brackets",
97-
"testKey2" -> "with=equals"
98-
)
99-
100-
assert(LinktimePropertyParser.toMap(inputString).right.get == expected)
101-
}
10243
}

0 commit comments

Comments
 (0)