Skip to content

Commit 11b66b1

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

24 files changed

+1081
-86
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: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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+
import java.util.Optional
6+
7+
class RlimitOptionValue(grammar : Combinator) : GrammarOptionValue("config_parse_rlimit", grammar) {
8+
companion object {
9+
10+
val GENERIC_SEQ =
11+
AlternativeCombinator(
12+
OptionalWhitespacePrefix(FlexibleLiteralChoiceTerminal("infinity")),
13+
OptionalWhitespacePrefix(IntegerTerminal(0, Int.MAX_VALUE)))
14+
15+
val BYTE_SEQ = AlternativeCombinator(
16+
FlexibleLiteralChoiceTerminal("infinity"),
17+
SequenceCombinator(
18+
OptionalWhitespacePrefix(IntegerTerminal(0, Int.MAX_VALUE)),
19+
OptionalWhitespacePrefix(LiteralChoiceTerminal("K", "M", "G", "T", "P", "E"))
20+
),
21+
IntegerTerminal(0, Int.MAX_VALUE))
22+
23+
val TIME_SEQ = AlternativeCombinator(
24+
FlexibleLiteralChoiceTerminal("infinity"),
25+
OneOrMore(
26+
SequenceCombinator(
27+
OptionalWhitespacePrefix(IntegerTerminal(0, Int.MAX_VALUE)),
28+
OptionalWhitespacePrefix(FlexibleLiteralChoiceTerminal("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"))
29+
)
30+
),
31+
IntegerTerminal(0, Int.MAX_VALUE)
32+
)
33+
34+
val NICE_SEQ = AlternativeCombinator(
35+
SequenceCombinator(LiteralChoiceTerminal("+", "-"), IntegerTerminal(0, 21)),
36+
SequenceCombinator(IntegerTerminal(0, 41)),
37+
)
38+
39+
val COLON = LiteralChoiceTerminal(":")
40+
41+
val BYTE_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(BYTE_SEQ, COLON, BYTE_SEQ), BYTE_SEQ), EOF())
42+
val TIME_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(TIME_SEQ, COLON, TIME_SEQ), TIME_SEQ), EOF())
43+
val GENERIC_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(GENERIC_SEQ, COLON, GENERIC_SEQ), GENERIC_SEQ), EOF())
44+
val NICE_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(NICE_SEQ, COLON, NICE_SEQ), NICE_SEQ), EOF())
45+
46+
47+
val validators = mapOf(
48+
// Exec.LimitCPU, config_parse_rlimit, RLIMIT_CPU, offsetof(Settings, rlimit)
49+
Validator("config_parse_rlimit", "RLIMIT_CPU") to RlimitOptionValue(TIME_RLIMIT),
50+
// Exec.LimitFSIZE, config_parse_rlimit, RLIMIT_FSIZE, offsetof(Settings, rlimit)
51+
Validator("config_parse_rlimit", "RLIMIT_FSIZE") to RlimitOptionValue(BYTE_RLIMIT),
52+
// Exec.LimitDATA, config_parse_rlimit, RLIMIT_DATA, offsetof(Settings, rlimit)
53+
Validator("config_parse_rlimit", "RLIMIT_DATA") to RlimitOptionValue(BYTE_RLIMIT),
54+
// Exec.LimitSTACK, config_parse_rlimit, RLIMIT_STACK, offsetof(Settings, rlimit)
55+
Validator("config_parse_rlimit", "RLIMIT_STACK") to RlimitOptionValue(BYTE_RLIMIT),
56+
// Exec.LimitCORE, config_parse_rlimit, RLIMIT_CORE, offsetof(Settings, rlimit)
57+
Validator("config_parse_rlimit", "RLIMIT_CORE") to RlimitOptionValue(BYTE_RLIMIT),
58+
// Exec.LimitRSS, config_parse_rlimit, RLIMIT_RSS, offsetof(Settings, rlimit)
59+
Validator("config_parse_rlimit", "RLIMIT_RSS") to RlimitOptionValue(BYTE_RLIMIT),
60+
// Exec.LimitNOFILE, config_parse_rlimit, RLIMIT_NOFILE, offsetof(Settings, rlimit)
61+
Validator("config_parse_rlimit", "RLIMIT_NOFILE") to RlimitOptionValue(GENERIC_RLIMIT),
62+
// Exec.LimitAS, config_parse_rlimit, RLIMIT_AS, offsetof(Settings, rlimit)
63+
Validator("config_parse_rlimit", "RLIMIT_AS") to RlimitOptionValue(BYTE_RLIMIT),
64+
// Exec.LimitNPROC, config_parse_rlimit, RLIMIT_NPROC, offsetof(Settings, rlimit)
65+
Validator("config_parse_rlimit", "RLIMIT_NPROC") to RlimitOptionValue(GENERIC_RLIMIT),
66+
// Exec.LimitMEMLOCK, config_parse_rlimit, RLIMIT_MEMLOCK, offsetof(Settings, rlimit)
67+
Validator("config_parse_rlimit", "RLIMIT_MEMLOCK") to RlimitOptionValue(BYTE_RLIMIT),
68+
// Exec.LimitLOCKS, config_parse_rlimit, RLIMIT_LOCKS, offsetof(Settings, rlimit)
69+
Validator("config_parse_rlimit", "RLIMIT_LOCKS") to RlimitOptionValue(GENERIC_RLIMIT),
70+
// Exec.LimitSIGPENDING, config_parse_rlimit, RLIMIT_SIGPENDING, offsetof(Settings, rlimit)
71+
Validator("config_parse_rlimit", "RLIMIT_SIGPENDING") to RlimitOptionValue(GENERIC_RLIMIT),
72+
// Exec.LimitMSGQUEUE, config_parse_rlimit, RLIMIT_MSGQUEUE, offsetof(Settings, rlimit)
73+
Validator("config_parse_rlimit", "RLIMIT_MSGQUEUE") to RlimitOptionValue(BYTE_RLIMIT),
74+
// Exec.LimitNICE, config_parse_rlimit, RLIMIT_NICE, offsetof(Settings, rlimit)
75+
Validator("config_parse_rlimit", "RLIMIT_NICE") to RlimitOptionValue(NICE_RLIMIT),
76+
// Exec.LimitRTPRIO, config_parse_rlimit, RLIMIT_RTPRIO, offsetof(Settings, rlimit)
77+
Validator("config_parse_rlimit", "RLIMIT_RTPRIO") to RlimitOptionValue(GENERIC_RLIMIT),
78+
// Exec.LimitRTTIME, config_parse_rlimit, RLIMIT_RTTIME, offsetof(Settings, rlimit)
79+
Validator("config_parse_rlimit", "RLIMIT_RTTIME") to RlimitOptionValue(TIME_RLIMIT),
80+
)
81+
}
82+
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import kotlin.math.max
55
/**
66
* This is a sequence of tokens that must match any of them.
77
*/
8-
class AlternativeCombinator(vararg val tokens: Combinator) : Combinator {
8+
open class AlternativeCombinator(vararg val tokens: Combinator) : Combinator {
99

1010
fun match(value: String, offset: Int, f: (Combinator, String, Int) -> MatchResult): MatchResult {
1111

@@ -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 & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ open class GrammarOptionValue(
5050
}
5151

5252
holder.registerProblem(property.valueNode.psi, "${property.key}'s value does not match the expected format. Possible reasons include unrecognized characters or premature end of input.", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, tr)
53-
54-
5553
return
5654
}
5755

@@ -96,9 +94,9 @@ open class GrammarOptionValue(
9694
}
9795
}
9896

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

104102

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import kotlin.math.max
55
/**
66
* This is a sequence of tokens that must match all of them.
77
*/
8-
class SequenceCombinator(vararg val tokens: Combinator) : Combinator {
8+
open class SequenceCombinator(vararg val tokens: Combinator) : Combinator {
99

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

0 commit comments

Comments
 (0)