Skip to content

Commit 6c838af

Browse files
author
Steve Ramage
committed
feat: Add support LimitCPU=,LimitData,.... (Resolves #312)
1 parent a9a26c6 commit 6c838af

File tree

11 files changed

+464
-15
lines changed

11 files changed

+464
-15
lines changed

src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/SemanticDataRepository.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ class SemanticDataRepository private constructor() {
120120
validatorMap.putAll(ImagePolicyOptionValue.validators)
121121
validatorMap.putAll(CPUWeightOptionValue.validators)
122122
validatorMap.putAll(CPUSharesOptionValue.validators)
123+
124+
validatorMap.putAll(RlimitOptionValue.validators)
123125
// Scopes are not supported since they aren't standard unit files.
124126
fileClassToSectionNameToKeyValuesFromDoc["unit"]?.remove(SCOPE_KEYWORD)
125127
fileClassToSectionToKeyAndValidatorMap["unit"]?.remove(SCOPE_KEYWORD)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.Validator
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
5+
6+
class RlimitOptionValue(grammar : Combinator) : GrammarOptionValue("config_parse_rlimit", grammar) {
7+
companion object {
8+
9+
val GENERIC_SEQ = AlternativeCombinator(LiteralChoiceTerminal("infinity"), IntegerTerminal(0, Int.MAX_VALUE))
10+
val BYTE_SEQ = AlternativeCombinator(LiteralChoiceTerminal("infinity"), SequenceCombinator(IntegerTerminal(0, Int.MAX_VALUE), OptionalWhitespacePrefix(LiteralChoiceTerminal("K", "M", "G", "T", "P", "E"))), IntegerTerminal(0, Int.MAX_VALUE))
11+
val TIME_SEQ = AlternativeCombinator(
12+
LiteralChoiceTerminal("infinity"),
13+
SequenceCombinator(
14+
IntegerTerminal(0, Int.MAX_VALUE),
15+
OptionalWhitespacePrefix(LiteralChoiceTerminal("usec", "us", "μs", "msec", "ms", "seconds", "second", "sec", "s", "minutes", "minute", "min", " m", "hours", "hour", "hr", "h", "days", "day", " d", "weeks", " week", "w", "months", "month", " M", "years", "year", "y"))
16+
)
17+
,
18+
IntegerTerminal(0, Int.MAX_VALUE)
19+
)
20+
21+
val NICE_SEQ = AlternativeCombinator(
22+
SequenceCombinator(LiteralChoiceTerminal("+", "-"), IntegerTerminal(0, 21)),
23+
SequenceCombinator(IntegerTerminal(0, 41)),
24+
)
25+
26+
27+
28+
val COLON = LiteralChoiceTerminal(":")
29+
val BYTE_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(BYTE_SEQ, COLON, BYTE_SEQ), BYTE_SEQ), EOF())
30+
val TIME_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(TIME_SEQ, COLON, TIME_SEQ), TIME_SEQ), EOF())
31+
val GENERIC_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(GENERIC_SEQ, COLON, GENERIC_SEQ), GENERIC_SEQ), EOF())
32+
val NICE_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(NICE_SEQ, COLON, NICE_SEQ), NICE_SEQ), EOF())
33+
34+
35+
val validators = mapOf(
36+
// Exec.LimitCPU, config_parse_rlimit, RLIMIT_CPU, offsetof(Settings, rlimit)
37+
Validator("config_parse_rlimit", "RLIMIT_CPU") to RlimitOptionValue(TIME_RLIMIT),
38+
// Exec.LimitFSIZE, config_parse_rlimit, RLIMIT_FSIZE, offsetof(Settings, rlimit)
39+
Validator("config_parse_rlimit", "RLIMIT_FSIZE") to RlimitOptionValue(BYTE_RLIMIT),
40+
// Exec.LimitDATA, config_parse_rlimit, RLIMIT_DATA, offsetof(Settings, rlimit)
41+
Validator("config_parse_rlimit", "RLIMIT_DATA") to RlimitOptionValue(BYTE_RLIMIT),
42+
// Exec.LimitSTACK, config_parse_rlimit, RLIMIT_STACK, offsetof(Settings, rlimit)
43+
Validator("config_parse_rlimit", "RLIMIT_STACK") to RlimitOptionValue(BYTE_RLIMIT),
44+
// Exec.LimitCORE, config_parse_rlimit, RLIMIT_CORE, offsetof(Settings, rlimit)
45+
Validator("config_parse_rlimit", "RLIMIT_CORE") to RlimitOptionValue(BYTE_RLIMIT),
46+
// Exec.LimitRSS, config_parse_rlimit, RLIMIT_RSS, offsetof(Settings, rlimit)
47+
Validator("config_parse_rlimit", "RLIMIT_RSS") to RlimitOptionValue(BYTE_RLIMIT),
48+
// Exec.LimitNOFILE, config_parse_rlimit, RLIMIT_NOFILE, offsetof(Settings, rlimit)
49+
Validator("config_parse_rlimit", "RLIMIT_NOFILE") to RlimitOptionValue(GENERIC_RLIMIT),
50+
// Exec.LimitAS, config_parse_rlimit, RLIMIT_AS, offsetof(Settings, rlimit)
51+
Validator("config_parse_rlimit", "RLIMIT_AS") to RlimitOptionValue(BYTE_RLIMIT),
52+
// Exec.LimitNPROC, config_parse_rlimit, RLIMIT_NPROC, offsetof(Settings, rlimit)
53+
Validator("config_parse_rlimit", "RLIMIT_NPROC") to RlimitOptionValue(GENERIC_RLIMIT),
54+
// Exec.LimitMEMLOCK, config_parse_rlimit, RLIMIT_MEMLOCK, offsetof(Settings, rlimit)
55+
Validator("config_parse_rlimit", "RLIMIT_MEMLOCK") to RlimitOptionValue(BYTE_RLIMIT),
56+
// Exec.LimitLOCKS, config_parse_rlimit, RLIMIT_LOCKS, offsetof(Settings, rlimit)
57+
Validator("config_parse_rlimit", "RLIMIT_LOCKS") to RlimitOptionValue(GENERIC_RLIMIT),
58+
// Exec.LimitSIGPENDING, config_parse_rlimit, RLIMIT_SIGPENDING, offsetof(Settings, rlimit)
59+
Validator("config_parse_rlimit", "RLIMIT_SIGPENDING") to RlimitOptionValue(GENERIC_RLIMIT),
60+
// Exec.LimitMSGQUEUE, config_parse_rlimit, RLIMIT_MSGQUEUE, offsetof(Settings, rlimit)
61+
Validator("config_parse_rlimit", "RLIMIT_MSGQUEUE") to RlimitOptionValue(BYTE_RLIMIT),
62+
// Exec.LimitNICE, config_parse_rlimit, RLIMIT_NICE, offsetof(Settings, rlimit)
63+
Validator("config_parse_rlimit", "RLIMIT_NICE") to RlimitOptionValue(NICE_RLIMIT),
64+
// Exec.LimitRTPRIO, config_parse_rlimit, RLIMIT_RTPRIO, offsetof(Settings, rlimit)
65+
Validator("config_parse_rlimit", "RLIMIT_RTPRIO") to RlimitOptionValue(GENERIC_RLIMIT),
66+
// Exec.LimitRTTIME, config_parse_rlimit, RLIMIT_RTTIME, offsetof(Settings, rlimit)
67+
Validator("config_parse_rlimit", "RLIMIT_RTTIME") to RlimitOptionValue(TIME_RLIMIT),
68+
)
69+
}
70+
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ class AlternativeCombinator(vararg val tokens: Combinator) : Combinator {
2020
return match
2121
}
2222

23-
24-
2523
if (match.tokens.size > longestTerminalMatch.size) {
2624
longestTerminalMatch = match.terminals
2725
longestTokenMatch = match.tokens

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@ open class GrammarOptionValue(
9696
}
9797
}
9898

99-
holder.registerProblem(property.valueNode.psi, "${property.key}'s value is correctly format but seems invalid.", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, tr, *quickFixes.toTypedArray())
99+
holder.registerProblem(property.valueNode.psi, "${property.key}'s value is correctly formatted but seems invalid.", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, tr, *quickFixes.toTypedArray())
100100
} else {
101-
holder.registerProblem(property.valueNode.psi, "${property.key}'s value is correctly format but seems invalid.", ProblemHighlightType.GENERIC_ERROR_OR_WARNING)
101+
holder.registerProblem(property.valueNode.psi, "${property.key}'s value is correctly formatted but seems invalid.", ProblemHighlightType.GENERIC_ERROR_OR_WARNING)
102102
}
103103

104104

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar
2+
3+
class OptionalWhitespacePrefix(val combinator: Combinator) : TerminalCombinator {
4+
5+
override fun SyntacticMatch(value: String, offset: Int): MatchResult {
6+
var newOffset = offset
7+
for(o in offset..<value.length) {
8+
if (value[o].isWhitespace()) {
9+
newOffset = o + 1
10+
} else {
11+
break
12+
}
13+
}
14+
15+
return combinator.SyntacticMatch(value, newOffset)
16+
}
17+
18+
override fun SemanticMatch(value: String, offset: Int): MatchResult {
19+
var newOffset = offset
20+
for(o in offset..<value.length) {
21+
if (value[o].isWhitespace()) {
22+
newOffset = o + 1
23+
} else {
24+
break
25+
}
26+
}
27+
28+
return combinator.SemanticMatch(value, newOffset)
29+
}
30+
}

src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/InvalidValidInspectionForCPUShares.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class InvalidValidInspectionForCPUShares : AbstractUnitFileTest() {
5959
// Verification
6060
assertSize(1, highlights)
6161
val info = highlights[0]
62-
AbstractUnitFileTest.Companion.assertStringContains("CPUShares's value is correctly format but seems invalid", info!!.description)
62+
AbstractUnitFileTest.Companion.assertStringContains("CPUShares's value is correctly formatted but seems invalid", info!!.description)
6363
TestCase.assertEquals("1", info.text)
6464
}
6565

@@ -80,7 +80,7 @@ class InvalidValidInspectionForCPUShares : AbstractUnitFileTest() {
8080
// Verification
8181
assertSize(1, highlights)
8282
val info = highlights[0]
83-
AbstractUnitFileTest.Companion.assertStringContains("CPUShares's value is correctly format but seems invalid", info!!.description)
83+
AbstractUnitFileTest.Companion.assertStringContains("CPUShares's value is correctly formatted but seems invalid", info!!.description)
8484
TestCase.assertEquals("-10", info.text)
8585
}
8686

@@ -102,7 +102,7 @@ class InvalidValidInspectionForCPUShares : AbstractUnitFileTest() {
102102
// Verification
103103
assertSize(1, highlights)
104104
val info = highlights[0]
105-
AbstractUnitFileTest.Companion.assertStringContains("CPUShares's value is correctly format but seems invalid", info!!.description)
105+
AbstractUnitFileTest.Companion.assertStringContains("CPUShares's value is correctly formatted but seems invalid", info!!.description)
106106
TestCase.assertEquals("262145", info.text)
107107
}
108108

src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/InvalidValidInspectionForCPUWeight.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class InvalidValidInspectionForCPUWeight : AbstractUnitFileTest() {
7676
// Verification
7777
assertSize(1, highlights)
7878
val info = highlights[0]
79-
AbstractUnitFileTest.Companion.assertStringContains("CPUWeight's value is correctly format but seems invalid", info!!.description)
79+
AbstractUnitFileTest.Companion.assertStringContains("CPUWeight's value is correctly formatted but seems invalid", info!!.description)
8080
TestCase.assertEquals("0", info.text)
8181
}
8282

@@ -97,7 +97,7 @@ class InvalidValidInspectionForCPUWeight : AbstractUnitFileTest() {
9797
// Verification
9898
assertSize(1, highlights)
9999
val info = highlights[0]
100-
AbstractUnitFileTest.Companion.assertStringContains("CPUWeight's value is correctly format but seems invalid", info!!.description)
100+
AbstractUnitFileTest.Companion.assertStringContains("CPUWeight's value is correctly formatted but seems invalid", info!!.description)
101101
TestCase.assertEquals("-10", info.text)
102102
}
103103

@@ -119,7 +119,7 @@ class InvalidValidInspectionForCPUWeight : AbstractUnitFileTest() {
119119
// Verification
120120
assertSize(1, highlights)
121121
val info = highlights[0]
122-
AbstractUnitFileTest.Companion.assertStringContains("CPUWeight's value is correctly format but seems invalid", info!!.description)
122+
AbstractUnitFileTest.Companion.assertStringContains("CPUWeight's value is correctly formatted but seems invalid", info!!.description)
123123
TestCase.assertEquals("-100000", info.text)
124124
}
125125

src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/InvalidValidInspectionForImagePolicy.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class InvalidValidInspectionForImagePolicy : AbstractUnitFileTest() {
4141
// Verification
4242
assertSize(1, highlights)
4343
val info = highlights[0]
44-
AbstractUnitFileTest.Companion.assertStringContains("RootImagePolicy's value is correctly format but seems invalid", info!!.description)
44+
AbstractUnitFileTest.Companion.assertStringContains("RootImagePolicy's value is correctly formatted but seems invalid", info!!.description)
4545
TestCase.assertEquals("opt", info.text)
4646
}
4747

@@ -62,7 +62,7 @@ class InvalidValidInspectionForImagePolicy : AbstractUnitFileTest() {
6262
// Verification
6363
assertSize(1, highlights)
6464
val info = highlights[0]
65-
AbstractUnitFileTest.Companion.assertStringContains("RootImagePolicy's value is correctly format but seems invalid", info!!.description)
65+
AbstractUnitFileTest.Companion.assertStringContains("RootImagePolicy's value is correctly formatted but seems invalid", info!!.description)
6666
TestCase.assertEquals("unsigned", info.text)
6767
}
6868

@@ -85,7 +85,7 @@ class InvalidValidInspectionForImagePolicy : AbstractUnitFileTest() {
8585
assertSize(1, highlights)
8686
val info = highlights[0]
8787

88-
AbstractUnitFileTest.Companion.assertStringContains("RootImagePolicy's value is correctly format but seems invalid", info!!.description)
88+
AbstractUnitFileTest.Companion.assertStringContains("RootImagePolicy's value is correctly formatted but seems invalid", info!!.description)
8989
TestCase.assertEquals("used", info.text)
9090
assertContainsQuickfix(info, "Replace 'used' with 'absent'")
9191
}
@@ -128,7 +128,7 @@ class InvalidValidInspectionForImagePolicy : AbstractUnitFileTest() {
128128
// Verification
129129
assertSize(1, highlights)
130130
val info = highlights[0]
131-
AbstractUnitFileTest.Companion.assertStringContains("RootImagePolicy's value is correctly format but seems invalid", info!!.description)
131+
AbstractUnitFileTest.Companion.assertStringContains("RootImagePolicy's value is correctly formatted but seems invalid", info!!.description)
132132
TestCase.assertEquals("used", info.text)
133133
assertContainsQuickfix(info, "Replace 'used' with 'absent'")
134134
}

0 commit comments

Comments
 (0)