xref: /Universal-ctags/parsers/systemdunit.c (revision 6b1a862e526d5017f9f212a321f59d67c859d521)
15f69efd8SMasatake YAMATO /*
25f69efd8SMasatake YAMATO *
35f69efd8SMasatake YAMATO *   Copyright (c) 2015, Red Hat, Inc.
45f69efd8SMasatake YAMATO *   Copyright (c) 2015, Masatake YAMATO
55f69efd8SMasatake YAMATO *
65f69efd8SMasatake YAMATO *   This source code is released for free distribution under the terms of the
75f69efd8SMasatake YAMATO *   GNU General Public License version 2 or (at your option) any later version.
85f69efd8SMasatake YAMATO *
95f69efd8SMasatake YAMATO */
105f69efd8SMasatake YAMATO 
115f69efd8SMasatake YAMATO /*
125f69efd8SMasatake YAMATO *   INCLUDE FILES
135f69efd8SMasatake YAMATO */
145f69efd8SMasatake YAMATO #include "general.h"  /* must always come first */
155f69efd8SMasatake YAMATO 
165f69efd8SMasatake YAMATO #include <ctype.h>
175f69efd8SMasatake YAMATO #include <string.h>
185f69efd8SMasatake YAMATO 
195f69efd8SMasatake YAMATO #include "entry.h"
2087214e15SMasatake YAMATO #include "iniconf.h"
210d502ef0SMasatake YAMATO #include "parse.h"
225f69efd8SMasatake YAMATO #include "read.h"
235f69efd8SMasatake YAMATO #include "routines.h"
245f69efd8SMasatake YAMATO #include "vstring.h"
255f69efd8SMasatake YAMATO #include "xtag.h"
265f69efd8SMasatake YAMATO 
275f69efd8SMasatake YAMATO 
28ed9b023fSMasatake YAMATO 
295f69efd8SMasatake YAMATO /*
305f69efd8SMasatake YAMATO *   DATA DEFINITIONS
315f69efd8SMasatake YAMATO */
325f69efd8SMasatake YAMATO typedef enum {
335f69efd8SMasatake YAMATO 	K_UNIT,
345f69efd8SMasatake YAMATO } systemdUnitKind;
355f69efd8SMasatake YAMATO 
365f69efd8SMasatake YAMATO typedef enum {
375f69efd8SMasatake YAMATO 	R_UNIT_Requires,
385f69efd8SMasatake YAMATO 	R_UNIT_Wants,
395f69efd8SMasatake YAMATO 	R_UNIT_After,
405f69efd8SMasatake YAMATO 	R_UNIT_Before,
415f69efd8SMasatake YAMATO 	R_UNIT_RequiredBy,
425f69efd8SMasatake YAMATO 	R_UNIT_WantedBy,
435f69efd8SMasatake YAMATO 
445f69efd8SMasatake YAMATO } systemdUnitRole;
455f69efd8SMasatake YAMATO 
4613457258SMasatake YAMATO static roleDefinition SystemdUnitUnitRoles [] = {
47ce990805SThomas Braun 	{ true, "Requires", "referred in Requires key" },
48ce990805SThomas Braun 	{ true, "Wants", "referred in Wants key" },
49ce990805SThomas Braun 	{ true, "After", "referred in After key" },
50ce990805SThomas Braun 	{ true, "Before", "referred in Before key" },
51ce990805SThomas Braun 	{ true, "RequiredBy", "referred in RequiredBy key" },
52ce990805SThomas Braun 	{ true, "WantedBy", "referred in WantedBy key" },
535f69efd8SMasatake YAMATO 	/* ... */
545f69efd8SMasatake YAMATO };
555f69efd8SMasatake YAMATO 
56e112e8abSMasatake YAMATO static kindDefinition SystemdUnitKinds [] = {
57ce990805SThomas Braun 	{ true, 'u', "unit", "units",
58ce990805SThomas Braun 	  .referenceOnly = true, ATTACH_ROLES(SystemdUnitUnitRoles)},
595f69efd8SMasatake YAMATO };
605f69efd8SMasatake YAMATO 
roleOf(const char * key,int kind)61f92e6bf2SMasatake YAMATO static int roleOf (const char* key, int kind)
625f69efd8SMasatake YAMATO {
635f69efd8SMasatake YAMATO 	int i;
645f69efd8SMasatake YAMATO 
65f92e6bf2SMasatake YAMATO 	for (i = 0; i < SystemdUnitKinds [kind].nRoles; i++)
665f69efd8SMasatake YAMATO 	{
67f92e6bf2SMasatake YAMATO 		if (strcmp (SystemdUnitKinds [kind].roles[i].name, key) == 0)
685f69efd8SMasatake YAMATO 			return i;
695f69efd8SMasatake YAMATO 	}
705f69efd8SMasatake YAMATO 
715f69efd8SMasatake YAMATO 	return -1;
725f69efd8SMasatake YAMATO }
735f69efd8SMasatake YAMATO 
makeSystemdReferencedUnit(const char * value,int kind,int role)7416a2541cSMasatake YAMATO static void makeSystemdReferencedUnit (const char *value, int kind, int role)
755f69efd8SMasatake YAMATO {
765f69efd8SMasatake YAMATO 	vString *unit = vStringNew ();
775f69efd8SMasatake YAMATO 
785f69efd8SMasatake YAMATO 	while (*value != '\0')
795f69efd8SMasatake YAMATO 	{
805f69efd8SMasatake YAMATO 		if (*value == ',')
815f69efd8SMasatake YAMATO 		{
8216a2541cSMasatake YAMATO 			makeSimpleRefTag (unit, kind, role);
835f69efd8SMasatake YAMATO 			vStringClear (unit);
845f69efd8SMasatake YAMATO 		}
855f69efd8SMasatake YAMATO 		else if (! isspace ((int) *value))
865f69efd8SMasatake YAMATO 			vStringPut (unit, *value);
875f69efd8SMasatake YAMATO 
885f69efd8SMasatake YAMATO 		value++;
895f69efd8SMasatake YAMATO 	}
905f69efd8SMasatake YAMATO 
915f69efd8SMasatake YAMATO 	if (vStringLength (unit) > 0)
9216a2541cSMasatake YAMATO 		makeSimpleRefTag (unit, kind, role);
935f69efd8SMasatake YAMATO 	vStringDelete (unit);
945f69efd8SMasatake YAMATO }
955f69efd8SMasatake YAMATO 
newDataCallback(iniconfSubparser * s CTAGS_ATTR_UNUSED,const char * section CTAGS_ATTR_UNUSED,const char * key,const char * value)96e4d16241SMasatake YAMATO static void newDataCallback (iniconfSubparser *s CTAGS_ATTR_UNUSED,
97e4d16241SMasatake YAMATO 							 const char *section CTAGS_ATTR_UNUSED, const char *key, const char *value)
985f69efd8SMasatake YAMATO {
995f69efd8SMasatake YAMATO 	int r;
1005f69efd8SMasatake YAMATO 
1015f69efd8SMasatake YAMATO 	if (isXtagEnabled (XTAG_REFERENCE_TAGS) && value)
1025f69efd8SMasatake YAMATO 	{
103f92e6bf2SMasatake YAMATO 		r = roleOf (key, K_UNIT);
1045f69efd8SMasatake YAMATO 		if (r >= 0)
10516a2541cSMasatake YAMATO 			makeSystemdReferencedUnit (value, K_UNIT, r);
1065f69efd8SMasatake YAMATO 	}
1075f69efd8SMasatake YAMATO }
1085f69efd8SMasatake YAMATO 
findSystemdUnitTags(void)1095f69efd8SMasatake YAMATO static void findSystemdUnitTags (void)
1105f69efd8SMasatake YAMATO {
111ed9b023fSMasatake YAMATO 	scheduleRunningBaseparser (0);
1125f69efd8SMasatake YAMATO }
1135f69efd8SMasatake YAMATO 
SystemdUnitParser(void)1145f69efd8SMasatake YAMATO extern parserDefinition* SystemdUnitParser (void)
1155f69efd8SMasatake YAMATO {
11692350fe4SMasatake YAMATO 	static const char *const extensions [] = { "service", "socket", "device",
1175f69efd8SMasatake YAMATO 											   "mount", "automount", "swap", "target",
11892350fe4SMasatake YAMATO 											   "path", "timer", "snapshot",
11992350fe4SMasatake YAMATO 											   "slice", NULL };
120ed9b023fSMasatake YAMATO 	static iniconfSubparser systemdUnitSubparser = {
121ed9b023fSMasatake YAMATO 		.subparser = {
122ed9b023fSMasatake YAMATO 			.direction = SUBPARSER_SUB_RUNS_BASE,
123ed9b023fSMasatake YAMATO 		},
124ed9b023fSMasatake YAMATO 		.newDataNotify = newDataCallback,
125ed9b023fSMasatake YAMATO 	};
126ed9b023fSMasatake YAMATO 	static parserDependency dependencies [] = {
127ed9b023fSMasatake YAMATO 		[0] = { DEPTYPE_SUBPARSER, "Iniconf", &systemdUnitSubparser },
128ed9b023fSMasatake YAMATO 	};
129ed9b023fSMasatake YAMATO 
1305f69efd8SMasatake YAMATO 	parserDefinition* const def = parserNew ("SystemdUnit");
131ed9b023fSMasatake YAMATO 
132ed9b023fSMasatake YAMATO 	def->dependencies = dependencies;
133ed9b023fSMasatake YAMATO 	def->dependencyCount = ARRAY_SIZE(dependencies);
13409ae690fSMasatake YAMATO 	def->kindTable      = SystemdUnitKinds;
1355f69efd8SMasatake YAMATO 	def->kindCount  = ARRAY_SIZE (SystemdUnitKinds);
1365f69efd8SMasatake YAMATO 	def->extensions = extensions;
1375f69efd8SMasatake YAMATO 	def->parser     = findSystemdUnitTags;
138*6b1a862eSMasatake YAMATO 	def->useCork    = CORK_QUEUE;
1395f69efd8SMasatake YAMATO 	return def;
1405f69efd8SMasatake YAMATO }
141