1c93810eaSMasatake YAMATO /*
2c93810eaSMasatake YAMATO *
3c93810eaSMasatake YAMATO * Copyright (c) 2016, Masatake YAMATO
4c93810eaSMasatake YAMATO * Copyright (c) 2016, Red Hat, K.K.
5c93810eaSMasatake YAMATO *
6c93810eaSMasatake YAMATO * This source code is released for free distribution under the terms of the
7c93810eaSMasatake YAMATO * GNU General Public License version 2 or (at your option) any later version.
8c93810eaSMasatake YAMATO *
9c93810eaSMasatake YAMATO * This module contains functions for generating tags for RelaxNG.
10c93810eaSMasatake YAMATO *
11c93810eaSMasatake YAMATO * https://www.oasis-open.org/committees/relax-ng/spec-20010811.html
12c93810eaSMasatake YAMATO *
13c93810eaSMasatake YAMATO */
14c93810eaSMasatake YAMATO
15c93810eaSMasatake YAMATO #include "general.h" /* must always come first */
1614781660SMasatake YAMATO #include "entry.h"
17c93810eaSMasatake YAMATO #include "parse.h"
18c93810eaSMasatake YAMATO #include "read.h"
195866d1baSMasatake YAMATO #include "xml.h"
20c93810eaSMasatake YAMATO
21c93810eaSMasatake YAMATO typedef enum {
22c93810eaSMasatake YAMATO K_ELEMENT,
23c93810eaSMasatake YAMATO K_ATTRIBUTE,
24c93810eaSMasatake YAMATO K_NAMED_PATTERN,
25c93810eaSMasatake YAMATO } relaxngKind;
26c93810eaSMasatake YAMATO
27e112e8abSMasatake YAMATO static kindDefinition RelaxNGKinds [] = {
28ce990805SThomas Braun { true, 'e', "element", "elements" },
29ce990805SThomas Braun { true, 'a', "attribute", "attributes" },
30ce990805SThomas Braun { true, 'n', "namedPattern", "named patterns" },
31c93810eaSMasatake YAMATO };
32c93810eaSMasatake YAMATO
33c93810eaSMasatake YAMATO enum relaxngXpathTable {
34c93810eaSMasatake YAMATO TABLE_MAIN, TABLE_ELEMENT_NAME, TABLE_PATTERN, TABLE_GRAMMAR, TABLE_DEFINE_NAME,
35c93810eaSMasatake YAMATO };
36c93810eaSMasatake YAMATO
37c93810eaSMasatake YAMATO static void relaxngMakeAndFindTagsUnderElement (xmlNode *node,
38513a7223SMasatake YAMATO const char *xpath,
39c93810eaSMasatake YAMATO const struct sTagXpathRecurSpec *spec,
40c93810eaSMasatake YAMATO xmlXPathContext *ctx,
41c93810eaSMasatake YAMATO void *userData);
42c93810eaSMasatake YAMATO static void relaxngMakeAndFindTagsUnderDefine (xmlNode *node,
43513a7223SMasatake YAMATO const char *xpath,
44c93810eaSMasatake YAMATO const struct sTagXpathRecurSpec *spec,
45c93810eaSMasatake YAMATO xmlXPathContext *ctx,
46c93810eaSMasatake YAMATO void *userData);
47c93810eaSMasatake YAMATO
48c93810eaSMasatake YAMATO static void relaxngFindTags (xmlNode *node,
49513a7223SMasatake YAMATO const char *xpath,
50c93810eaSMasatake YAMATO const struct sTagXpathRecurSpec *spec,
51c93810eaSMasatake YAMATO xmlXPathContext *ctx,
52c93810eaSMasatake YAMATO void *userData);
53c93810eaSMasatake YAMATO
54c93810eaSMasatake YAMATO
55c93810eaSMasatake YAMATO static tagXpathTable relaxngXpathMainTable [] = {
56c93810eaSMasatake YAMATO { "/*[local-name()='element']",
57c93810eaSMasatake YAMATO LXPATH_TABLE_DO_RECUR,
58c93810eaSMasatake YAMATO { .recurSpec = { relaxngMakeAndFindTagsUnderElement, TABLE_PATTERN } }
59c93810eaSMasatake YAMATO },
60c93810eaSMasatake YAMATO { "/*[local-name()='grammar']",
61c93810eaSMasatake YAMATO LXPATH_TABLE_DO_RECUR,
62c93810eaSMasatake YAMATO { .recurSpec = { relaxngFindTags, TABLE_GRAMMAR } }
63c93810eaSMasatake YAMATO },
64c93810eaSMasatake YAMATO };
65c93810eaSMasatake YAMATO
66c93810eaSMasatake YAMATO static void makeTagWithScope (xmlNode *node,
67513a7223SMasatake YAMATO const char *xpath,
68c93810eaSMasatake YAMATO const struct sTagXpathMakeTagSpec *spec,
69c93810eaSMasatake YAMATO struct sTagEntryInfo *tag,
70c93810eaSMasatake YAMATO void *userData);
71c93810eaSMasatake YAMATO
72c93810eaSMasatake YAMATO static tagXpathTable relaxngXpathPatternTable [] = {
73c93810eaSMasatake YAMATO { "./*[local-name()='element']",
74c93810eaSMasatake YAMATO LXPATH_TABLE_DO_RECUR,
75c93810eaSMasatake YAMATO { .recurSpec = { relaxngMakeAndFindTagsUnderElement, TABLE_PATTERN } }
76c93810eaSMasatake YAMATO },
77c93810eaSMasatake YAMATO { "./*[local-name()='attribute']/@name",
78c93810eaSMasatake YAMATO LXPATH_TABLE_DO_MAKE,
7924b256e3SMasatake YAMATO { .makeTagSpec = { K_ATTRIBUTE, ROLE_DEFINITION_INDEX,
80c93810eaSMasatake YAMATO makeTagWithScope } }
81c93810eaSMasatake YAMATO },
82c93810eaSMasatake YAMATO { "./*[not(local-name()='element')][not(local-name()='attribute')]",
83c93810eaSMasatake YAMATO LXPATH_TABLE_DO_RECUR,
84c93810eaSMasatake YAMATO { .recurSpec = { relaxngFindTags, TABLE_PATTERN } }
85c93810eaSMasatake YAMATO },
86c93810eaSMasatake YAMATO };
87c93810eaSMasatake YAMATO
88c93810eaSMasatake YAMATO
89c93810eaSMasatake YAMATO static void makeTagWithUpdatingScope (xmlNode *node,
90513a7223SMasatake YAMATO const char *xpath,
91c93810eaSMasatake YAMATO const struct sTagXpathMakeTagSpec *spec,
92c93810eaSMasatake YAMATO struct sTagEntryInfo *tag,
93c93810eaSMasatake YAMATO void *userData);
94c93810eaSMasatake YAMATO
95c93810eaSMasatake YAMATO static tagXpathTable relaxngXpathElementNameTable [] = {
96c93810eaSMasatake YAMATO { "@name",
97c93810eaSMasatake YAMATO LXPATH_TABLE_DO_MAKE,
9824b256e3SMasatake YAMATO { .makeTagSpec = { K_ELEMENT, ROLE_DEFINITION_INDEX,
99c93810eaSMasatake YAMATO makeTagWithUpdatingScope } }
100c93810eaSMasatake YAMATO },
101c93810eaSMasatake YAMATO };
102c93810eaSMasatake YAMATO
103c93810eaSMasatake YAMATO static tagXpathTable relaxngXpathGrammerTable [] = {
104c93810eaSMasatake YAMATO { "./*[local-name()='start']",
105c93810eaSMasatake YAMATO LXPATH_TABLE_DO_RECUR,
106c93810eaSMasatake YAMATO { .recurSpec = { relaxngFindTags, TABLE_PATTERN } }
107c93810eaSMasatake YAMATO },
108c93810eaSMasatake YAMATO { "./*[local-name()='define']",
109c93810eaSMasatake YAMATO LXPATH_TABLE_DO_RECUR,
110c93810eaSMasatake YAMATO { .recurSpec = { relaxngMakeAndFindTagsUnderDefine, TABLE_PATTERN } }
111c93810eaSMasatake YAMATO }
112c93810eaSMasatake YAMATO };
113c93810eaSMasatake YAMATO
114c93810eaSMasatake YAMATO static tagXpathTable relaxngXpathDefineNameTable [] = {
115c93810eaSMasatake YAMATO { "@name",
116c93810eaSMasatake YAMATO LXPATH_TABLE_DO_MAKE,
11724b256e3SMasatake YAMATO { .makeTagSpec = { K_NAMED_PATTERN, ROLE_DEFINITION_INDEX,
118c93810eaSMasatake YAMATO makeTagWithUpdatingScope } }
119c93810eaSMasatake YAMATO },
120c93810eaSMasatake YAMATO };
121c93810eaSMasatake YAMATO
122c93810eaSMasatake YAMATO static tagXpathTableTable relaxngXpathTableTable[] = {
123c93810eaSMasatake YAMATO [TABLE_MAIN] = { ARRAY_AND_SIZE (relaxngXpathMainTable) },
124c93810eaSMasatake YAMATO [TABLE_ELEMENT_NAME] = { ARRAY_AND_SIZE (relaxngXpathElementNameTable) },
125c93810eaSMasatake YAMATO [TABLE_PATTERN] = { ARRAY_AND_SIZE (relaxngXpathPatternTable) },
126c93810eaSMasatake YAMATO [TABLE_GRAMMAR] = { ARRAY_AND_SIZE (relaxngXpathGrammerTable) },
127c93810eaSMasatake YAMATO [TABLE_DEFINE_NAME] = { ARRAY_AND_SIZE (relaxngXpathDefineNameTable) },
128c93810eaSMasatake YAMATO };
129c93810eaSMasatake YAMATO
130c93810eaSMasatake YAMATO
131c93810eaSMasatake YAMATO static void
relaxngMakeAndFindTags(xmlNode * node,const char * xpath,const struct sTagXpathRecurSpec * spec,xmlXPathContext * ctx,int nextTable,void * userData)132c93810eaSMasatake YAMATO relaxngMakeAndFindTags(xmlNode *node,
133513a7223SMasatake YAMATO const char *xpath,
134c93810eaSMasatake YAMATO const struct sTagXpathRecurSpec *spec,
135c93810eaSMasatake YAMATO xmlXPathContext *ctx,
136c93810eaSMasatake YAMATO int nextTable,
137c93810eaSMasatake YAMATO void *userData)
138c93810eaSMasatake YAMATO {
139c93810eaSMasatake YAMATO int corkIndex = *(int *)userData;
140c93810eaSMasatake YAMATO
141971e7196SMasatake YAMATO findXMLTags (ctx, node, nextTable, &corkIndex);
142c93810eaSMasatake YAMATO
143513a7223SMasatake YAMATO relaxngFindTags (node, xpath, spec, ctx, &corkIndex);
144c93810eaSMasatake YAMATO }
145c93810eaSMasatake YAMATO
146c93810eaSMasatake YAMATO static void
relaxngMakeAndFindTagsUnderElement(xmlNode * node,const char * xpath,const struct sTagXpathRecurSpec * spec,xmlXPathContext * ctx,void * userData)147c93810eaSMasatake YAMATO relaxngMakeAndFindTagsUnderElement (xmlNode *node,
148513a7223SMasatake YAMATO const char *xpath,
149c93810eaSMasatake YAMATO const struct sTagXpathRecurSpec *spec,
150c93810eaSMasatake YAMATO xmlXPathContext *ctx,
151c93810eaSMasatake YAMATO void *userData)
152c93810eaSMasatake YAMATO {
153513a7223SMasatake YAMATO relaxngMakeAndFindTags (node, xpath, spec, ctx, TABLE_ELEMENT_NAME, userData);
154c93810eaSMasatake YAMATO }
155c93810eaSMasatake YAMATO
156c93810eaSMasatake YAMATO static void
relaxngMakeAndFindTagsUnderDefine(xmlNode * node,const char * xpath,const struct sTagXpathRecurSpec * spec,xmlXPathContext * ctx,void * userData)157c93810eaSMasatake YAMATO relaxngMakeAndFindTagsUnderDefine (xmlNode *node,
158513a7223SMasatake YAMATO const char *xpath,
159c93810eaSMasatake YAMATO const struct sTagXpathRecurSpec *spec,
160c93810eaSMasatake YAMATO xmlXPathContext *ctx,
161c93810eaSMasatake YAMATO void *userData)
162c93810eaSMasatake YAMATO {
163513a7223SMasatake YAMATO relaxngMakeAndFindTags (node, xpath, spec, ctx, TABLE_DEFINE_NAME, userData);
164c93810eaSMasatake YAMATO }
165c93810eaSMasatake YAMATO
166c93810eaSMasatake YAMATO static void
relaxngFindTags(xmlNode * node,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathRecurSpec * spec,xmlXPathContext * ctx,void * userData)167c93810eaSMasatake YAMATO relaxngFindTags (xmlNode *node,
168513a7223SMasatake YAMATO const char *xpath CTAGS_ATTR_UNUSED,
169c93810eaSMasatake YAMATO const struct sTagXpathRecurSpec *spec,
170c93810eaSMasatake YAMATO xmlXPathContext *ctx,
171c93810eaSMasatake YAMATO void *userData)
172c93810eaSMasatake YAMATO {
173c93810eaSMasatake YAMATO int corkIndex = *(int *)userData;
174c93810eaSMasatake YAMATO
175971e7196SMasatake YAMATO findXMLTags (ctx, node, spec->nextTable, &corkIndex);
176c93810eaSMasatake YAMATO }
177c93810eaSMasatake YAMATO
178c93810eaSMasatake YAMATO static void
setScope(struct sTagEntryInfo * tag,int index)179c93810eaSMasatake YAMATO setScope (struct sTagEntryInfo *tag, int index)
180c93810eaSMasatake YAMATO {
181f92e6bf2SMasatake YAMATO tag->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;
182c93810eaSMasatake YAMATO tag->extensionFields.scopeName = NULL;
183c93810eaSMasatake YAMATO tag->extensionFields.scopeIndex = index;
184c93810eaSMasatake YAMATO
185c93810eaSMasatake YAMATO }
186c93810eaSMasatake YAMATO
187c93810eaSMasatake YAMATO static void
makeTagWithUpdatingScope(xmlNode * node CTAGS_ATTR_UNUSED,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathMakeTagSpec * spec CTAGS_ATTR_UNUSED,struct sTagEntryInfo * tag,void * userData)188e4d16241SMasatake YAMATO makeTagWithUpdatingScope (xmlNode *node CTAGS_ATTR_UNUSED,
189513a7223SMasatake YAMATO const char *xpath CTAGS_ATTR_UNUSED,
190e4d16241SMasatake YAMATO const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,
191c93810eaSMasatake YAMATO struct sTagEntryInfo *tag,
192c93810eaSMasatake YAMATO void *userData)
193c93810eaSMasatake YAMATO {
194c93810eaSMasatake YAMATO int *corkIndex = userData;
195c93810eaSMasatake YAMATO
196c93810eaSMasatake YAMATO
19731404383SMasatake YAMATO #if 0
198c93810eaSMasatake YAMATO if (*corkIndex == CORK_NIL)
19931404383SMasatake YAMATO /* TODO: mark tag as an entry point */
200c93810eaSMasatake YAMATO ;
20131404383SMasatake YAMATO #endif
20231404383SMasatake YAMATO
203c93810eaSMasatake YAMATO setScope (tag, *corkIndex);
204c93810eaSMasatake YAMATO
205c93810eaSMasatake YAMATO *corkIndex = makeTagEntry (tag);
206c93810eaSMasatake YAMATO }
207c93810eaSMasatake YAMATO
208c93810eaSMasatake YAMATO
209c93810eaSMasatake YAMATO static void
findRelaxNGTags(void)210c93810eaSMasatake YAMATO findRelaxNGTags (void)
211c93810eaSMasatake YAMATO {
2125866d1baSMasatake YAMATO scheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);
213c93810eaSMasatake YAMATO }
214c93810eaSMasatake YAMATO
215c93810eaSMasatake YAMATO static void
makeTagWithScope(xmlNode * node CTAGS_ATTR_UNUSED,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathMakeTagSpec * spec CTAGS_ATTR_UNUSED,struct sTagEntryInfo * tag,void * userData)2168ccb7ee9SJiří Techet makeTagWithScope (xmlNode *node CTAGS_ATTR_UNUSED,
217513a7223SMasatake YAMATO const char *xpath CTAGS_ATTR_UNUSED,
2188ccb7ee9SJiří Techet const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,
219c93810eaSMasatake YAMATO struct sTagEntryInfo *tag,
220c93810eaSMasatake YAMATO void *userData)
221c93810eaSMasatake YAMATO {
222c93810eaSMasatake YAMATO setScope (tag, *(int *)userData);
223c93810eaSMasatake YAMATO
224c93810eaSMasatake YAMATO makeTagEntry (tag);
225c93810eaSMasatake YAMATO }
226c93810eaSMasatake YAMATO
2275866d1baSMasatake YAMATO static void
runXPathEngine(xmlSubparser * s,xmlXPathContext * ctx,xmlNode * root)2285866d1baSMasatake YAMATO runXPathEngine(xmlSubparser *s,
2295866d1baSMasatake YAMATO xmlXPathContext *ctx, xmlNode *root)
2305866d1baSMasatake YAMATO {
2315866d1baSMasatake YAMATO int corkIndex = CORK_NIL;
2325866d1baSMasatake YAMATO
2335866d1baSMasatake YAMATO findXMLTags (ctx, root, TABLE_MAIN, &corkIndex);
2345866d1baSMasatake YAMATO }
2355866d1baSMasatake YAMATO
2365866d1baSMasatake YAMATO static xmlSubparser relaxngSubparser = {
2375866d1baSMasatake YAMATO .subparser = {
2385866d1baSMasatake YAMATO .direction = SUBPARSER_BI_DIRECTION,
2395866d1baSMasatake YAMATO },
2405866d1baSMasatake YAMATO .runXPathEngine = runXPathEngine,
2415866d1baSMasatake YAMATO };
2425866d1baSMasatake YAMATO
243c93810eaSMasatake YAMATO extern parserDefinition*
RelaxNGParser(void)244c93810eaSMasatake YAMATO RelaxNGParser (void)
245c93810eaSMasatake YAMATO {
246c93810eaSMasatake YAMATO static const char *const extensions [] = { "rng", NULL };
247c93810eaSMasatake YAMATO parserDefinition* const def = parserNew ("RelaxNG");
248c93810eaSMasatake YAMATO /* static selectLanguage selectors[] = { selectByDTD, NULL }; */
2495866d1baSMasatake YAMATO static parserDependency dependencies [] = {
2505866d1baSMasatake YAMATO [0] = { DEPTYPE_SUBPARSER, "XML", &relaxngSubparser },
2515866d1baSMasatake YAMATO };
252c93810eaSMasatake YAMATO
25309ae690fSMasatake YAMATO def->kindTable = RelaxNGKinds;
254c93810eaSMasatake YAMATO def->kindCount = ARRAY_SIZE (RelaxNGKinds);
255c93810eaSMasatake YAMATO def->extensions = extensions;
256c93810eaSMasatake YAMATO def->parser = findRelaxNGTags;
257c93810eaSMasatake YAMATO def->tagXpathTableTable = relaxngXpathTableTable;
258c93810eaSMasatake YAMATO def->tagXpathTableCount = ARRAY_SIZE (relaxngXpathTableTable);
259*6b1a862eSMasatake YAMATO def->useCork = CORK_QUEUE;
260c93810eaSMasatake YAMATO /* def->selectLanguage = selectors; */
2615866d1baSMasatake YAMATO def->dependencies = dependencies;
2625866d1baSMasatake YAMATO def->dependencyCount = ARRAY_SIZE (dependencies);
2635866d1baSMasatake YAMATO
264c93810eaSMasatake YAMATO return def;
265c93810eaSMasatake YAMATO }
266