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