Skip to content

Commit 0d339da

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

24 files changed

+999
-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: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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+
OneOrMore(
14+
SequenceCombinator(
15+
OptionalWhitespacePrefix(IntegerTerminal(0, Int.MAX_VALUE)),
16+
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"))
17+
)
18+
),
19+
IntegerTerminal(0, Int.MAX_VALUE)
20+
)
21+
22+
val NICE_SEQ = AlternativeCombinator(
23+
SequenceCombinator(LiteralChoiceTerminal("+", "-"), IntegerTerminal(0, 21)),
24+
SequenceCombinator(IntegerTerminal(0, 41)),
25+
)
26+
27+
val COLON = LiteralChoiceTerminal(":")
28+
val BYTE_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(BYTE_SEQ, COLON, BYTE_SEQ), BYTE_SEQ), EOF())
29+
val TIME_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(TIME_SEQ, COLON, TIME_SEQ), TIME_SEQ), EOF())
30+
val GENERIC_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(GENERIC_SEQ, COLON, GENERIC_SEQ), GENERIC_SEQ), EOF())
31+
val NICE_RLIMIT = SequenceCombinator(AlternativeCombinator(SequenceCombinator(NICE_SEQ, COLON, NICE_SEQ), NICE_SEQ), EOF())
32+
33+
34+
val validators = mapOf(
35+
// Exec.LimitCPU, config_parse_rlimit, RLIMIT_CPU, offsetof(Settings, rlimit)
36+
Validator("config_parse_rlimit", "RLIMIT_CPU") to RlimitOptionValue(TIME_RLIMIT),
37+
// Exec.LimitFSIZE, config_parse_rlimit, RLIMIT_FSIZE, offsetof(Settings, rlimit)
38+
Validator("config_parse_rlimit", "RLIMIT_FSIZE") to RlimitOptionValue(BYTE_RLIMIT),
39+
// Exec.LimitDATA, config_parse_rlimit, RLIMIT_DATA, offsetof(Settings, rlimit)
40+
Validator("config_parse_rlimit", "RLIMIT_DATA") to RlimitOptionValue(BYTE_RLIMIT),
41+
// Exec.LimitSTACK, config_parse_rlimit, RLIMIT_STACK, offsetof(Settings, rlimit)
42+
Validator("config_parse_rlimit", "RLIMIT_STACK") to RlimitOptionValue(BYTE_RLIMIT),
43+
// Exec.LimitCORE, config_parse_rlimit, RLIMIT_CORE, offsetof(Settings, rlimit)
44+
Validator("config_parse_rlimit", "RLIMIT_CORE") to RlimitOptionValue(BYTE_RLIMIT),
45+
// Exec.LimitRSS, config_parse_rlimit, RLIMIT_RSS, offsetof(Settings, rlimit)
46+
Validator("config_parse_rlimit", "RLIMIT_RSS") to RlimitOptionValue(BYTE_RLIMIT),
47+
// Exec.LimitNOFILE, config_parse_rlimit, RLIMIT_NOFILE, offsetof(Settings, rlimit)
48+
Validator("config_parse_rlimit", "RLIMIT_NOFILE") to RlimitOptionValue(GENERIC_RLIMIT),
49+
// Exec.LimitAS, config_parse_rlimit, RLIMIT_AS, offsetof(Settings, rlimit)
50+
Validator("config_parse_rlimit", "RLIMIT_AS") to RlimitOptionValue(BYTE_RLIMIT),
51+
// Exec.LimitNPROC, config_parse_rlimit, RLIMIT_NPROC, offsetof(Settings, rlimit)
52+
Validator("config_parse_rlimit", "RLIMIT_NPROC") to RlimitOptionValue(GENERIC_RLIMIT),
53+
// Exec.LimitMEMLOCK, config_parse_rlimit, RLIMIT_MEMLOCK, offsetof(Settings, rlimit)
54+
Validator("config_parse_rlimit", "RLIMIT_MEMLOCK") to RlimitOptionValue(BYTE_RLIMIT),
55+
// Exec.LimitLOCKS, config_parse_rlimit, RLIMIT_LOCKS, offsetof(Settings, rlimit)
56+
Validator("config_parse_rlimit", "RLIMIT_LOCKS") to RlimitOptionValue(GENERIC_RLIMIT),
57+
// Exec.LimitSIGPENDING, config_parse_rlimit, RLIMIT_SIGPENDING, offsetof(Settings, rlimit)
58+
Validator("config_parse_rlimit", "RLIMIT_SIGPENDING") to RlimitOptionValue(GENERIC_RLIMIT),
59+
// Exec.LimitMSGQUEUE, config_parse_rlimit, RLIMIT_MSGQUEUE, offsetof(Settings, rlimit)
60+
Validator("config_parse_rlimit", "RLIMIT_MSGQUEUE") to RlimitOptionValue(BYTE_RLIMIT),
61+
// Exec.LimitNICE, config_parse_rlimit, RLIMIT_NICE, offsetof(Settings, rlimit)
62+
Validator("config_parse_rlimit", "RLIMIT_NICE") to RlimitOptionValue(NICE_RLIMIT),
63+
// Exec.LimitRTPRIO, config_parse_rlimit, RLIMIT_RTPRIO, offsetof(Settings, rlimit)
64+
Validator("config_parse_rlimit", "RLIMIT_RTPRIO") to RlimitOptionValue(GENERIC_RLIMIT),
65+
// Exec.LimitRTTIME, config_parse_rlimit, RLIMIT_RTTIME, offsetof(Settings, rlimit)
66+
Validator("config_parse_rlimit", "RLIMIT_RTTIME") to RlimitOptionValue(TIME_RLIMIT),
67+
)
68+
}
69+
}

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)