1 -- Copyright 2016 Christian Hesse
2 -- systemd unit file LPeg lexer.
4 local l
= require('lexer')
5 local token
, word_match
= l
.token
, l
.word_match
6 local P
, R
, S
= lpeg
.P
, lpeg
.R
, lpeg
.S
8 local M
= {_NAME
= 'systemd'}
11 local ws
= token(l
.WHITESPACE
, l
.space^
1)
14 local comment
= token(l
.COMMENT
, l
.starts_line(S(';#')) * l
.nonnewline^
0)
17 local sq_str
= l
.delimited_range("'")
18 local dq_str
= l
.delimited_range('"')
19 local section_word
= word_match
{
31 local string = token(l
.STRING
, sq_str
+ dq_str
+ '[' * section_word
* ']')
34 local dec
= l
.digit^
1 * ('_' * l
.digit^
1)^
0
35 local oct_num
= '0' * S('01234567_')^
1
36 local integer
= S('+-')^
-1 * (l
.hex_num
+ oct_num
+ dec
)
37 local number = token(l
.NUMBER
, (l
.float
+ integer
))
40 local keyword
= token(l
.KEYWORD
, word_match({
57 -- special system units
59 'ctrl-alt-del.target',
64 'display-manager.service',
71 'hybrid-sleep.target',
78 'network-online.target',
84 'initrd-root-fs.target',
98 'system-update.target',
102 -- special system units for devices
108 -- special passive system units
109 'cryptsetup-pre.target',
110 'local-fs-pre.target',
112 'network-pre.target',
114 'nss-user-lookup.target',
115 'remote-fs-pre.target',
119 -- specail slice units
125 -- environment variables
148 local option_word
= word_match
{
149 -- unit section options
161 'PropagatesReloadTo',
162 'ReloadPropagatedFrom',
171 'DefaultDependencies',
174 'JobTimeoutRebootArgument',
175 'StartLimitInterval',
179 'ConditionArchitecture',
180 'ConditionVirtualization',
182 'ConditionKernelCommandLine',
184 'ConditionCapability',
186 'ConditionNeedsUpdate',
187 'ConditionFirstBoot',
188 'ConditionPathExists',
189 'ConditionPathExistsGlob',
190 'ConditionPathIsDirectory',
191 'ConditionPathIsSymbolicLink',
192 'ConditionPathIsMountPoint',
193 'ConditionPathIsReadWrite',
194 'ConditionDirectoryNotEmpty',
195 'ConditionFileNotEmpty',
196 'ConditionFileIsExecutable',
197 'AssertArchitecture',
198 'AssertVirtualization',
200 'AssertKernelCommandLine',
207 'AssertPathExistsGlob',
208 'AssertPathIsDirectory',
209 'AssertPathIsSymbolicLink',
210 'AssertPathIsMountPoint',
211 'AssertPathIsReadWrite',
212 'AssertDirectoryNotEmpty',
213 'AssertFileNotEmpty',
214 'AssertFileIsExecutable',
217 -- install section options
224 -- service section options
245 'RestartPreventExitStatus',
246 'RestartForceExitStatus',
247 'PermissionsStartOnly',
248 'RootDirectoryStartOnly',
253 'FileDescriptorStoreMax',
254 'USBFunctionDescriptors',
255 'USBFunctionStrings',
257 -- socket section options
260 'ListenSequentialPacket',
264 'ListenMessageQueue',
279 'KeepAliveIntervalSec',
293 'SELinuxContextFromNet',
295 'MessageQueueMaxMessages',
296 'MessageQueueMessageSize',
311 'FileDescriptorName',
313 -- mount section options
322 -- path section options
332 -- timer section options
340 'RandomizedDelaySec',
346 -- exec section options
351 'SupplementaryGroups',
355 'IOSchedulingPriority',
356 'CPUSchedulingPolicy',
357 'CPUSchedulingPriority',
358 'CPUSchedulingResetOnFork',
393 'CapabilityBoundingSet',
394 'AmbientCapabilities',
397 'ReadWriteDirectories',
398 'ReadOnlyDirectories',
399 'InaccessibleDirectories',
414 'SystemCallErrorNumber',
415 'SystemCallArchitectures',
416 'RestrictAddressFamilies',
419 'RuntimeDirectoryMode'
421 local preproc
= token(l
.PREPROCESSOR
, option_word
)
424 local word
= (l
.alpha
+ '_') * (l
.alnum
+ S('_.'))^
0
425 local identifier
= token(l
.IDENTIFIER
, word
)
428 local operator
= token(l
.OPERATOR
, '=')
432 {'keyword', keyword
},
434 {'preproc', preproc
},
435 {'identifier', identifier
},
436 {'comment', comment
},
438 {'operator', operator
},