xref: /Universal-ctags/parsers/dbusintrospect.c (revision 6b1a862e526d5017f9f212a321f59d67c859d521)
1443d16ccSMasatake YAMATO /*
2443d16ccSMasatake YAMATO *
3443d16ccSMasatake YAMATO *   Copyright (c) 2016, Masatake YAMATO
4443d16ccSMasatake YAMATO *   Copyright (c) 2016, Red Hat, K.K.
5443d16ccSMasatake YAMATO *
6443d16ccSMasatake YAMATO *   This source code is released for free distribution under the terms of the
7443d16ccSMasatake YAMATO *   GNU General Public License version 2 or (at your option) any later version.
8443d16ccSMasatake YAMATO *
9443d16ccSMasatake YAMATO *   This module contains functions for generating tags for
10443d16ccSMasatake YAMATO *   <!DOCTYPE node PUBLIC
11443d16ccSMasatake YAMATO *             "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
12443d16ccSMasatake YAMATO *             "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
1385f38e5cSMasatake YAMATO *   and
14443d16ccSMasatake YAMATO *
1585f38e5cSMasatake YAMATO *	<!DOCTYPE node PUBLIC
1685f38e5cSMasatake YAMATO *             "-//freedesktop//DTD D-BUS Introspection 0.1//EN"
1785f38e5cSMasatake YAMATO *             "http://www.freedesktop.org/software/dbus/introspection.dtd">
1885f38e5cSMasatake YAMATO **
19443d16ccSMasatake YAMATO */
20443d16ccSMasatake YAMATO 
21443d16ccSMasatake YAMATO #include "general.h"	/* must always come first */
2214781660SMasatake YAMATO #include "entry.h"
23443d16ccSMasatake YAMATO #include "parse.h"
24443d16ccSMasatake YAMATO #include "read.h"
25443d16ccSMasatake YAMATO #include "routines.h"
269c30a9c4SMasatake YAMATO #include "selectors.h"
27db9ab903SMasatake YAMATO #include "xml.h"
28443d16ccSMasatake YAMATO 
2985f38e5cSMasatake YAMATO #include <string.h>
3085f38e5cSMasatake YAMATO 
31443d16ccSMasatake YAMATO 
32443d16ccSMasatake YAMATO typedef enum {
33ba0cb4f3SMasatake YAMATO 	K_ARG, K_INTERFACE, K_METHOD, K_SIGNAL, K_PROPERTY, K_NODE,
34443d16ccSMasatake YAMATO } dbusIntrospectKind;
35443d16ccSMasatake YAMATO 
36e112e8abSMasatake YAMATO static kindDefinition DbusIntrospectKinds [] = {
37ba0cb4f3SMasatake YAMATO 	{ true,  'a', "arg",       "arguments"  },
38ce990805SThomas Braun 	{ true,  'i', "interface", "interfaces" },
39ce990805SThomas Braun 	{ true,  'm', "method",    "methods"    },
40ce990805SThomas Braun 	{ true,  's', "signal",    "signals"    },
41ce990805SThomas Braun 	{ true,  'p', "property",  "properties" },
4285f38e5cSMasatake YAMATO 	{ true,  'n', "node",      "nodes"      },
43443d16ccSMasatake YAMATO };
44443d16ccSMasatake YAMATO 
4585f38e5cSMasatake YAMATO static void dbusIntrospectFindTagsUnderMain (xmlNode *node,
46513a7223SMasatake YAMATO 						  const char *xpath,
47443d16ccSMasatake YAMATO 						  const struct sTagXpathRecurSpec *spec,
48443d16ccSMasatake YAMATO 						  xmlXPathContext *ctx,
49443d16ccSMasatake YAMATO 						  void *userData);
5085f38e5cSMasatake YAMATO static void makeTagForMainName (xmlNode *node,
51513a7223SMasatake YAMATO 				     const char *xpath,
52443d16ccSMasatake YAMATO 				     const struct sTagXpathMakeTagSpec *spec,
53443d16ccSMasatake YAMATO 				     struct sTagEntryInfo *tag,
54443d16ccSMasatake YAMATO 				     void *userData);
55443d16ccSMasatake YAMATO static void makeTagWithScope (xmlNode *node,
56513a7223SMasatake YAMATO 			      const char *xpath,
57443d16ccSMasatake YAMATO 			      const struct sTagXpathMakeTagSpec *spec,
58443d16ccSMasatake YAMATO 			      struct sTagEntryInfo *tag,
59443d16ccSMasatake YAMATO 			      void *userData);
6085f38e5cSMasatake YAMATO static int decideKindForMainName (xmlNode *node,
61513a7223SMasatake YAMATO 				  const char *xpath,
6285f38e5cSMasatake YAMATO 			      const struct sTagXpathMakeTagSpec *spec,
6385f38e5cSMasatake YAMATO 			      void *userData);
64443d16ccSMasatake YAMATO 
6585f38e5cSMasatake YAMATO struct dbusIntrospectData {
6685f38e5cSMasatake YAMATO 	int scopeIndex;
6785f38e5cSMasatake YAMATO 	int kindForName;
6885f38e5cSMasatake YAMATO };
69443d16ccSMasatake YAMATO 
70ba0cb4f3SMasatake YAMATO static tagXpathTable dbusIntrospectXpathArgTable [] = {
71ba0cb4f3SMasatake YAMATO 	{ "arg",
72ba0cb4f3SMasatake YAMATO 	  LXPATH_TABLE_DO_RECUR,
73ba0cb4f3SMasatake YAMATO 	  { .recurSpec = { dbusIntrospectFindTagsUnderMain,
74ba0cb4f3SMasatake YAMATO 					   -1 } },
75443d16ccSMasatake YAMATO 	},
76ba0cb4f3SMasatake YAMATO };
77ba0cb4f3SMasatake YAMATO 
78ba0cb4f3SMasatake YAMATO enum dbusIntrospectXpathTable {
79ba0cb4f3SMasatake YAMATO 	TABLE_ROOT, TABLE_MAIN, TABLE_INTERFACE, TABLE_MAIN_NAME, TABLE_ARG,
80ba0cb4f3SMasatake YAMATO };
81ba0cb4f3SMasatake YAMATO 
82ba0cb4f3SMasatake YAMATO static tagXpathTable dbusIntrospectXpathInterfaceTable [] = {
83ba0cb4f3SMasatake YAMATO 	{ "method",
84ba0cb4f3SMasatake YAMATO 	  LXPATH_TABLE_DO_RECUR,
85ba0cb4f3SMasatake YAMATO 	  { .recurSpec = { dbusIntrospectFindTagsUnderMain,
86ba0cb4f3SMasatake YAMATO 					   TABLE_ARG, } }
87ba0cb4f3SMasatake YAMATO 	},
88ba0cb4f3SMasatake YAMATO 	{ "signal",
89ba0cb4f3SMasatake YAMATO 	  LXPATH_TABLE_DO_RECUR,
90ba0cb4f3SMasatake YAMATO 	  { .recurSpec = { dbusIntrospectFindTagsUnderMain,
91ba0cb4f3SMasatake YAMATO 					   TABLE_ARG, } }
92443d16ccSMasatake YAMATO 	},
93c2fd5283SMasatake YAMATO 	{ "property/@name",
94443d16ccSMasatake YAMATO 	  LXPATH_TABLE_DO_MAKE,
9524b256e3SMasatake YAMATO 	  { .makeTagSpec = { K_PROPERTY, ROLE_DEFINITION_INDEX,
96ba0cb4f3SMasatake YAMATO 						 makeTagWithScope, } }
97443d16ccSMasatake YAMATO 	},
98443d16ccSMasatake YAMATO };
99443d16ccSMasatake YAMATO 
100443d16ccSMasatake YAMATO static tagXpathTable dbusIntrospectXpathMainTable [] = {
10185f38e5cSMasatake YAMATO 	{ "interface",
102443d16ccSMasatake YAMATO 	  LXPATH_TABLE_DO_RECUR,
103ba0cb4f3SMasatake YAMATO 	  { .recurSpec = { dbusIntrospectFindTagsUnderMain,
104ba0cb4f3SMasatake YAMATO 					   TABLE_INTERFACE, } }
10585f38e5cSMasatake YAMATO 	},
10685f38e5cSMasatake YAMATO 	{ "node",
10785f38e5cSMasatake YAMATO 	  LXPATH_TABLE_DO_RECUR,
108ba0cb4f3SMasatake YAMATO 	  { .recurSpec = { dbusIntrospectFindTagsUnderMain,
109ba0cb4f3SMasatake YAMATO 					   TABLE_MAIN, } }
110443d16ccSMasatake YAMATO 	},
111443d16ccSMasatake YAMATO };
112443d16ccSMasatake YAMATO 
113443d16ccSMasatake YAMATO static tagXpathTable dbusIntrospectXpathMainNameTable [] = {
114443d16ccSMasatake YAMATO 	{ "@name",
115443d16ccSMasatake YAMATO 	  LXPATH_TABLE_DO_MAKE,
11624b256e3SMasatake YAMATO 	  { .makeTagSpec = { KIND_GHOST_INDEX, ROLE_DEFINITION_INDEX,
11785f38e5cSMasatake YAMATO 			     makeTagForMainName,
11885f38e5cSMasatake YAMATO 			     decideKindForMainName } }
11985f38e5cSMasatake YAMATO 	},
12085f38e5cSMasatake YAMATO };
12185f38e5cSMasatake YAMATO 
12285f38e5cSMasatake YAMATO static tagXpathTable dbusIntrospectXpathRootTable [] = {
12385f38e5cSMasatake YAMATO 	{ "/node",
12485f38e5cSMasatake YAMATO 	  LXPATH_TABLE_DO_RECUR,
125ba0cb4f3SMasatake YAMATO 	  { .recurSpec = { dbusIntrospectFindTagsUnderMain,
126ba0cb4f3SMasatake YAMATO 					   TABLE_MAIN, } }
127443d16ccSMasatake YAMATO 	},
128443d16ccSMasatake YAMATO };
129443d16ccSMasatake YAMATO 
130443d16ccSMasatake YAMATO static tagXpathTableTable dbusIntrospectXpathTableTable[] = {
13185f38e5cSMasatake YAMATO 	[TABLE_ROOT]      = { ARRAY_AND_SIZE (dbusIntrospectXpathRootTable)     },
132443d16ccSMasatake YAMATO 	[TABLE_MAIN]      = { ARRAY_AND_SIZE (dbusIntrospectXpathMainTable)     },
133443d16ccSMasatake YAMATO 	[TABLE_INTERFACE] = { ARRAY_AND_SIZE (dbusIntrospectXpathInterfaceTable)},
134443d16ccSMasatake YAMATO 	[TABLE_MAIN_NAME] = { ARRAY_AND_SIZE (dbusIntrospectXpathMainNameTable) },
135ba0cb4f3SMasatake YAMATO 	[TABLE_ARG]       = { ARRAY_AND_SIZE (dbusIntrospectXpathArgTable)      },
136443d16ccSMasatake YAMATO };
137443d16ccSMasatake YAMATO 
dbusIntrospectFindTagsUnderMain(xmlNode * node,const char * xpath,const struct sTagXpathRecurSpec * spec,xmlXPathContext * ctx,void * userData)13885f38e5cSMasatake YAMATO static void dbusIntrospectFindTagsUnderMain (xmlNode *node,
139104c1180SMasatake YAMATO 						  const char *xpath,
140ba0cb4f3SMasatake YAMATO 						  const struct sTagXpathRecurSpec *spec,
141443d16ccSMasatake YAMATO 						  xmlXPathContext *ctx,
14285f38e5cSMasatake YAMATO 						  void *userData)
143443d16ccSMasatake YAMATO {
14485f38e5cSMasatake YAMATO 	struct dbusIntrospectData *data = userData;
14585f38e5cSMasatake YAMATO 	int scopeIndex = data->scopeIndex;
14685f38e5cSMasatake YAMATO 
147104c1180SMasatake YAMATO 	if (!strcmp(xpath, "interface"))
14885f38e5cSMasatake YAMATO 		data->kindForName = K_INTERFACE;
149ba0cb4f3SMasatake YAMATO 	else if (!strcmp (xpath, "method"))
150ba0cb4f3SMasatake YAMATO 		data->kindForName = K_METHOD;
151ba0cb4f3SMasatake YAMATO 	else if (!strcmp (xpath, "signal"))
152ba0cb4f3SMasatake YAMATO 		data->kindForName = K_SIGNAL;
153ba0cb4f3SMasatake YAMATO 	else if (!strcmp (xpath, "arg"))
154ba0cb4f3SMasatake YAMATO 		data->kindForName = K_ARG;
15585f38e5cSMasatake YAMATO 	else
15685f38e5cSMasatake YAMATO 		data->kindForName = K_NODE;
157443d16ccSMasatake YAMATO 
158971e7196SMasatake YAMATO 	findXMLTags (ctx, node, TABLE_MAIN_NAME, data);
159ba0cb4f3SMasatake YAMATO 	if (spec->nextTable >= 0)
160971e7196SMasatake YAMATO 		findXMLTags (ctx, node, spec->nextTable, data);
16185f38e5cSMasatake YAMATO 	data->scopeIndex = scopeIndex;
162443d16ccSMasatake YAMATO }
163443d16ccSMasatake YAMATO 
makeTagWithScope(xmlNode * node CTAGS_ATTR_UNUSED,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathMakeTagSpec * spec CTAGS_ATTR_UNUSED,struct sTagEntryInfo * tag,void * userData)1648ccb7ee9SJiří Techet static void makeTagWithScope (xmlNode *node CTAGS_ATTR_UNUSED,
165513a7223SMasatake YAMATO 			      const char *xpath CTAGS_ATTR_UNUSED,
1668ccb7ee9SJiří Techet 			      const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,
167443d16ccSMasatake YAMATO 			      struct sTagEntryInfo *tag,
168443d16ccSMasatake YAMATO 			      void *userData)
169443d16ccSMasatake YAMATO {
17085f38e5cSMasatake YAMATO 	struct dbusIntrospectData *data = userData;
17185f38e5cSMasatake YAMATO 
172f92e6bf2SMasatake YAMATO 	tag->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;
173443d16ccSMasatake YAMATO 	tag->extensionFields.scopeName  = NULL;
17485f38e5cSMasatake YAMATO 	tag->extensionFields.scopeIndex = data->scopeIndex;
175443d16ccSMasatake YAMATO 
176443d16ccSMasatake YAMATO 	makeTagEntry (tag);
177443d16ccSMasatake YAMATO }
178443d16ccSMasatake YAMATO 
makeTagForMainName(xmlNode * node CTAGS_ATTR_UNUSED,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathMakeTagSpec * spec CTAGS_ATTR_UNUSED,struct sTagEntryInfo * tag,void * userData)17985f38e5cSMasatake YAMATO static void makeTagForMainName (xmlNode *node CTAGS_ATTR_UNUSED,
180513a7223SMasatake YAMATO 				     const char *xpath CTAGS_ATTR_UNUSED,
1818ccb7ee9SJiří Techet 				     const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,
182443d16ccSMasatake YAMATO 				     struct sTagEntryInfo *tag,
183443d16ccSMasatake YAMATO 				     void *userData)
184443d16ccSMasatake YAMATO {
18585f38e5cSMasatake YAMATO 	struct dbusIntrospectData *data = userData;
186443d16ccSMasatake YAMATO 
18785f38e5cSMasatake YAMATO 	tag->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;
18885f38e5cSMasatake YAMATO 	tag->extensionFields.scopeName  = NULL;
18985f38e5cSMasatake YAMATO 	tag->extensionFields.scopeIndex = data->scopeIndex;
19085f38e5cSMasatake YAMATO 
19185f38e5cSMasatake YAMATO 	data->scopeIndex = makeTagEntry (tag);
19285f38e5cSMasatake YAMATO }
19385f38e5cSMasatake YAMATO 
decideKindForMainName(xmlNode * node CTAGS_ATTR_UNUSED,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathMakeTagSpec * spec CTAGS_ATTR_UNUSED,void * userData)19485f38e5cSMasatake YAMATO static int decideKindForMainName (xmlNode *node CTAGS_ATTR_UNUSED,
195513a7223SMasatake YAMATO 			      const char *xpath CTAGS_ATTR_UNUSED,
19685f38e5cSMasatake YAMATO 			      const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,
19785f38e5cSMasatake YAMATO 			      void *userData)
19885f38e5cSMasatake YAMATO {
19985f38e5cSMasatake YAMATO 	return ((struct dbusIntrospectData *)userData)->kindForName;
200443d16ccSMasatake YAMATO }
201443d16ccSMasatake YAMATO 
202443d16ccSMasatake YAMATO static void
findDbusIntrospectTags(void)203443d16ccSMasatake YAMATO findDbusIntrospectTags (void)
204443d16ccSMasatake YAMATO {
205db9ab903SMasatake YAMATO 	scheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);
206db9ab903SMasatake YAMATO }
207db9ab903SMasatake YAMATO 
208db9ab903SMasatake YAMATO static void
runXPathEngine(xmlSubparser * s,xmlXPathContext * ctx,xmlNode * root)209db9ab903SMasatake YAMATO runXPathEngine(xmlSubparser *s,
210db9ab903SMasatake YAMATO 			   xmlXPathContext *ctx, xmlNode *root)
211db9ab903SMasatake YAMATO {
21285f38e5cSMasatake YAMATO 	struct dbusIntrospectData data = {
21385f38e5cSMasatake YAMATO 		.scopeIndex = CORK_NIL,
21485f38e5cSMasatake YAMATO 		.kindForName = KIND_GHOST_INDEX,
21585f38e5cSMasatake YAMATO 	};
216db9ab903SMasatake YAMATO 	findXMLTags (ctx, root, TABLE_ROOT, &data);
217443d16ccSMasatake YAMATO }
218443d16ccSMasatake YAMATO 
219db9ab903SMasatake YAMATO static xmlSubparser dbusIntrospectSubparser = {
220db9ab903SMasatake YAMATO 	.subparser = {
221db9ab903SMasatake YAMATO 		.direction = SUBPARSER_BI_DIRECTION,
222db9ab903SMasatake YAMATO 	},
223db9ab903SMasatake YAMATO 	.runXPathEngine = runXPathEngine,
224db9ab903SMasatake YAMATO };
225db9ab903SMasatake YAMATO 
226443d16ccSMasatake YAMATO extern parserDefinition*
DbusIntrospectParser(void)227443d16ccSMasatake YAMATO DbusIntrospectParser (void)
228443d16ccSMasatake YAMATO {
229443d16ccSMasatake YAMATO 	static const char *const extensions [] = { "xml", NULL };
230443d16ccSMasatake YAMATO 	parserDefinition* const def = parserNew ("DBusIntrospect");
231ff522ef8SMasatake YAMATO 	static selectLanguage selectors[] = { selectByXpathFileSpec, NULL };
232443d16ccSMasatake YAMATO 
2337fcb59fbSMasatake YAMATO 	static xpathFileSpec xpathFileSpecs[] = {
2347fcb59fbSMasatake YAMATO 		{
2357fcb59fbSMasatake YAMATO 			/* <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
2367fcb59fbSMasatake YAMATO 			   "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
2377fcb59fbSMasatake YAMATO 			   <node ... */
2387fcb59fbSMasatake YAMATO 			.externalID = "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN",
2397fcb59fbSMasatake YAMATO 			.systemID   = "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd",
2407fcb59fbSMasatake YAMATO 		},
24185f38e5cSMasatake YAMATO 		{
24285f38e5cSMasatake YAMATO 			.externalID = "-//freedesktop//DTD D-BUS Introspection 0.1//EN",
24385f38e5cSMasatake YAMATO 			.systemID = "http://www.freedesktop.org/software/dbus/introspection.dtd",
24485f38e5cSMasatake YAMATO 		},
24585f38e5cSMasatake YAMATO 		/* TODO: the following rule is too strong; parsers may conflicts each other
24685f38e5cSMasatake YAMATO 		 * when we implement more xpath based parsers. */
24785f38e5cSMasatake YAMATO 		{
24885f38e5cSMasatake YAMATO 			.rootElementName = "node",
24985f38e5cSMasatake YAMATO 			.nameInDTD       = "",
25085f38e5cSMasatake YAMATO 			.externalID      = "",
25185f38e5cSMasatake YAMATO 			.systemID        = "",
25285f38e5cSMasatake YAMATO 			.rootNSPrefix    = "",
25385f38e5cSMasatake YAMATO 			.rootNSHref      = "",
25485f38e5cSMasatake YAMATO 		},
2557fcb59fbSMasatake YAMATO 	};
256db9ab903SMasatake YAMATO 	static parserDependency dependencies [] = {
257db9ab903SMasatake YAMATO 		[0] = { DEPTYPE_SUBPARSER, "XML", &dbusIntrospectSubparser },
258db9ab903SMasatake YAMATO 	};
25909ae690fSMasatake YAMATO 	def->kindTable         = DbusIntrospectKinds;
260443d16ccSMasatake YAMATO 	def->kindCount     = ARRAY_SIZE (DbusIntrospectKinds);
261443d16ccSMasatake YAMATO 	def->extensions    = extensions;
262443d16ccSMasatake YAMATO 	def->parser        = findDbusIntrospectTags;
263443d16ccSMasatake YAMATO 	def->tagXpathTableTable = dbusIntrospectXpathTableTable;
264443d16ccSMasatake YAMATO 	def->tagXpathTableCount = ARRAY_SIZE (dbusIntrospectXpathTableTable);
265*6b1a862eSMasatake YAMATO 	def->useCork = CORK_QUEUE;
2669c30a9c4SMasatake YAMATO 	def->selectLanguage = selectors;
2677fcb59fbSMasatake YAMATO 	def->xpathFileSpecs = xpathFileSpecs;
2687fcb59fbSMasatake YAMATO 	def->xpathFileSpecCount = ARRAY_SIZE (xpathFileSpecs);
269db9ab903SMasatake YAMATO 	def->dependencies = dependencies;
270db9ab903SMasatake YAMATO 	def->dependencyCount = ARRAY_SIZE (dependencies);
2717fcb59fbSMasatake YAMATO 
272443d16ccSMasatake YAMATO 	return def;
273443d16ccSMasatake YAMATO }
274