Skip to content

Commit 3ecd32b

Browse files
SJrXclaude
andcommitted
refactor: use the shared case-insensitive BOOLEAN in network-route-addr validators
Drop NETWORK_ROUTE_ADDR_BOOLEAN_ANY_CASE now that BOOLEAN matches parse_boolean()'s STRCASE_IN_SET. IPv6SendRA=/IPv6PrefixDelegation= use the explicit PreferValidAlternativeCombinator(names, BOOLEAN) form, with case-sensitive names as string_table_lookup_from_string uses streq. IPProtocol= keeps ignoreCase (gperf --ignore-case plus an ascii_strlower retry) and moves to PreferValidAlternativeCombinator so the lenient name regex cannot shadow a number on the classic engine. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent e78e57d commit 3ecd32b

5 files changed

Lines changed: 29 additions & 17 deletions

File tree

‎src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseRouterPrefixDelegationOptionValue.kt‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
33
import com.intellij.codeInspection.ProblemsHolder
44
import net.sjrx.intellij.plugins.systemdunitfiles.psi.UnitFilePropertyType
55
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
6-
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.AlternativeCombinator
7-
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.NETWORK_ROUTE_ADDR_BOOLEAN_ANY_CASE
6+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.BOOLEAN
87
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF
98
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.FlexibleLiteralChoiceTerminal
9+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.PreferValidAlternativeCombinator
1010
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator
1111

1212
/*
@@ -29,15 +29,18 @@ import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.gram
2929
* Both keys share one (parser, ltype) registration, so the registered grammar is the union — a boolean,
3030
* or `static` / `dhcpv6` — which is exact for `IPv6PrefixDelegation=`. For `IPv6SendRA=`
3131
* [generateProblemDescriptors] branches on the key, as the C does, and checks against a boolean-only
32-
* grammar, so `IPv6SendRA=static` is flagged. Booleans are matched case-insensitively, as
33-
* parse_boolean() does. The names come before the boolean so the classic matcher tries them first.
32+
* grammar, so `IPv6SendRA=static` is flagged.
33+
*
34+
* string_table_lookup_from_string_with_boolean() runs parse_boolean() first (STRCASE_IN_SET, so `Yes`,
35+
* `TRUE`, `oFf` are fine), then a case-sensitive streq() lookup, so `Static` is refused. The table's
36+
* `no` / `yes` entries are left out of the names because [BOOLEAN] already covers them in any case.
3437
*/
3538
class ConfigParseRouterPrefixDelegationOptionValue : SimpleGrammarOptionValues(
3639
"config_parse_router_prefix_delegation",
3740
SequenceCombinator(
38-
AlternativeCombinator(
41+
PreferValidAlternativeCombinator(
3942
FlexibleLiteralChoiceTerminal("static", "dhcpv6"),
40-
NETWORK_ROUTE_ADDR_BOOLEAN_ANY_CASE,
43+
BOOLEAN,
4144
),
4245
EOF()
4346
)
@@ -55,7 +58,7 @@ class ConfigParseRouterPrefixDelegationOptionValue : SimpleGrammarOptionValues(
5558
// streq(lvalue, "IPv6SendRA") → parse_boolean() only.
5659
val SEND_RA_BOOLEAN_ONLY = SimpleGrammarOptionValues(
5760
"config_parse_router_prefix_delegation",
58-
SequenceCombinator(NETWORK_ROUTE_ADDR_BOOLEAN_ANY_CASE, EOF())
61+
SequenceCombinator(BOOLEAN, EOF())
5962
)
6063
}
6164
}

‎src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseRoutingPolicyRuleIpProtocolOptionValue.kt‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
22

33
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
4-
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.AlternativeCombinator
54
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.Checked
65
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF
76
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.FlexibleLiteralChoiceTerminal
87
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.NetworkRouteAddrSafeAtouTerminal
8+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.PreferValidAlternativeCombinator
99
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator
1010
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.safeAtouValue
1111

@@ -56,7 +56,7 @@ private val IP_PROTOCOL_NUMBERS = setOf(
5656
class ConfigParseRoutingPolicyRuleIpProtocolOptionValue : SimpleGrammarOptionValues(
5757
"config_parse_routing_policy_rule",
5858
SequenceCombinator(
59-
AlternativeCombinator(
59+
PreferValidAlternativeCombinator(
6060
FlexibleLiteralChoiceTerminal(*IP_PROTOCOL_NAMES, ignoreCase = true),
6161
Checked(NetworkRouteAddrSafeAtouTerminal(0, 256)) { text -> safeAtouValue(text)?.toInt() in IP_PROTOCOL_NUMBERS },
6262
),

‎src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/grammar/BatchNetworkRouteAddrCombinators.kt‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -429,12 +429,6 @@ fun ipIsMulticast(bytes: ByteArray): Boolean =
429429
if (bytes.size == 4) (bytes[0].toInt() and 0xF0) == 0xE0 else (bytes[0].toInt() and 0xFF) == 0xFF
430430

431431

432-
// ---------------------------------------------------------------------------------------------------
433-
// parse_boolean() (src/basic/parse-util.c) compares with STRCASE_IN_SET, so `Yes`, `TRUE` and `Off` are
434-
// all booleans. The shared [BOOLEAN] terminal is case-sensitive; this one is not.
435-
val NETWORK_ROUTE_ADDR_BOOLEAN_ANY_CASE = FlexibleLiteralChoiceTerminal(*BOOLEAN_SPELLINGS, ignoreCase = true)
436-
437-
438432
// ---------------------------------------------------------------------------------------------------
439433
// IPv6 prefixes — in_addr_prefix_from_string(…, AF_INET6, …) (src/basic/in-addr-util.c): an IPv6 literal
440434
// and an optional `/LEN`, where LEN goes through in_addr_parse_prefixlen → safe_atou8 (base 0) and must

‎src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseRouterPrefixDelegationOptionValueTest.kt‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,16 @@ class ConfigParseRouterPrefixDelegationOptionValueTest : AbstractUnitFileTest()
1616
IPv6SendRA=no
1717
IPv6SendRA=True
1818
IPv6SendRA=0
19+
IPv6SendRA=Yes
20+
IPv6SendRA=TRUE
21+
IPv6SendRA=oFf
1922
IPv6PrefixDelegation=static
2023
IPv6PrefixDelegation=dhcpv6
2124
IPv6PrefixDelegation=yes
25+
IPv6PrefixDelegation=Yes
26+
IPv6PrefixDelegation=TRUE
27+
IPv6PrefixDelegation=oFf
28+
IPv6PrefixDelegation=No
2229
""".trimIndent()
2330

2431
setupFileInEditor("file.network", file)
@@ -36,10 +43,13 @@ class ConfigParseRouterPrefixDelegationOptionValueTest : AbstractUnitFileTest()
3643
IPv6SendRA=both
3744
IPv6SendRA=static
3845
IPv6SendRA=dhcpv6
46+
IPv6PrefixDelegation=Static
47+
IPv6PrefixDelegation=DHCPv6
48+
IPv6PrefixDelegation=maybe
3949
""".trimIndent()
4050

4151
setupFileInEditor("file.network", file)
4252
enableInspection(InvalidValueInspection::class.java)
43-
assertSize(4, myFixture.doHighlighting())
53+
assertSize(7, myFixture.doHighlighting())
4454
}
4555
}

‎src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseRoutingPolicyRuleIpProtocolOptionValueTest.kt‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ class ConfigParseRoutingPolicyRuleIpProtocolOptionValueTest : AbstractUnitFileTe
2525
IPProtocol=144
2626
IPProtocol=0
2727
IPProtocol=58
28+
IPProtocol=TcP
29+
IPProtocol=IcMpV6
30+
IPProtocol=L2TP
2831
""".trimIndent()
2932

3033
setupFileInEditor("file.network", file)
@@ -44,10 +47,12 @@ class ConfigParseRoutingPolicyRuleIpProtocolOptionValueTest : AbstractUnitFileTe
4447
IPProtocol=-6
4548
IPProtocol=3
4649
IPProtocol=200
50+
IPProtocol=TcPx
51+
IPProtocol=Yes
4752
""".trimIndent()
4853

4954
setupFileInEditor("file.network", file)
5055
enableInspection(InvalidValueInspection::class.java)
51-
assertSize(6, myFixture.doHighlighting())
56+
assertSize(8, myFixture.doHighlighting())
5257
}
5358
}

0 commit comments

Comments
 (0)