1 /*
2 *
3 * Copyright (c) 2015, Red Hat, Inc.
4 * Copyright (c) 2015, Masatake YAMATO
5 *
6 * This source code is released for free distribution under the terms of the
7 * GNU General Public License version 2 or (at your option) any later version.
8 *
9 */
10
11 /*
12 * INCLUDE FILES
13 */
14 #include "general.h" /* must always come first */
15
16 #include <ctype.h>
17 #include <string.h>
18
19 #include "entry.h"
20 #include "iniconf.h"
21 #include "parse.h"
22 #include "read.h"
23 #include "routines.h"
24 #include "vstring.h"
25 #include "xtag.h"
26
27
28
29 /*
30 * DATA DEFINITIONS
31 */
32 typedef enum {
33 K_UNIT,
34 } systemdUnitKind;
35
36 typedef enum {
37 R_UNIT_Requires,
38 R_UNIT_Wants,
39 R_UNIT_After,
40 R_UNIT_Before,
41 R_UNIT_RequiredBy,
42 R_UNIT_WantedBy,
43
44 } systemdUnitRole;
45
46 static roleDefinition SystemdUnitUnitRoles [] = {
47 { true, "Requires", "referred in Requires key" },
48 { true, "Wants", "referred in Wants key" },
49 { true, "After", "referred in After key" },
50 { true, "Before", "referred in Before key" },
51 { true, "RequiredBy", "referred in RequiredBy key" },
52 { true, "WantedBy", "referred in WantedBy key" },
53 /* ... */
54 };
55
56 static kindDefinition SystemdUnitKinds [] = {
57 { true, 'u', "unit", "units",
58 .referenceOnly = true, ATTACH_ROLES(SystemdUnitUnitRoles)},
59 };
60
roleOf(const char * key,int kind)61 static int roleOf (const char* key, int kind)
62 {
63 int i;
64
65 for (i = 0; i < SystemdUnitKinds [kind].nRoles; i++)
66 {
67 if (strcmp (SystemdUnitKinds [kind].roles[i].name, key) == 0)
68 return i;
69 }
70
71 return -1;
72 }
73
makeSystemdReferencedUnit(const char * value,int kind,int role)74 static void makeSystemdReferencedUnit (const char *value, int kind, int role)
75 {
76 vString *unit = vStringNew ();
77
78 while (*value != '\0')
79 {
80 if (*value == ',')
81 {
82 makeSimpleRefTag (unit, kind, role);
83 vStringClear (unit);
84 }
85 else if (! isspace ((int) *value))
86 vStringPut (unit, *value);
87
88 value++;
89 }
90
91 if (vStringLength (unit) > 0)
92 makeSimpleRefTag (unit, kind, role);
93 vStringDelete (unit);
94 }
95
newDataCallback(iniconfSubparser * s CTAGS_ATTR_UNUSED,const char * section CTAGS_ATTR_UNUSED,const char * key,const char * value)96 static void newDataCallback (iniconfSubparser *s CTAGS_ATTR_UNUSED,
97 const char *section CTAGS_ATTR_UNUSED, const char *key, const char *value)
98 {
99 int r;
100
101 if (isXtagEnabled (XTAG_REFERENCE_TAGS) && value)
102 {
103 r = roleOf (key, K_UNIT);
104 if (r >= 0)
105 makeSystemdReferencedUnit (value, K_UNIT, r);
106 }
107 }
108
findSystemdUnitTags(void)109 static void findSystemdUnitTags (void)
110 {
111 scheduleRunningBaseparser (0);
112 }
113
SystemdUnitParser(void)114 extern parserDefinition* SystemdUnitParser (void)
115 {
116 static const char *const extensions [] = { "service", "socket", "device",
117 "mount", "automount", "swap", "target",
118 "path", "timer", "snapshot",
119 "slice", NULL };
120 static iniconfSubparser systemdUnitSubparser = {
121 .subparser = {
122 .direction = SUBPARSER_SUB_RUNS_BASE,
123 },
124 .newDataNotify = newDataCallback,
125 };
126 static parserDependency dependencies [] = {
127 [0] = { DEPTYPE_SUBPARSER, "Iniconf", &systemdUnitSubparser },
128 };
129
130 parserDefinition* const def = parserNew ("SystemdUnit");
131
132 def->dependencies = dependencies;
133 def->dependencyCount = ARRAY_SIZE(dependencies);
134 def->kindTable = SystemdUnitKinds;
135 def->kindCount = ARRAY_SIZE (SystemdUnitKinds);
136 def->extensions = extensions;
137 def->parser = findSystemdUnitTags;
138 def->useCork = CORK_QUEUE;
139 return def;
140 }
141