xref: /Universal-ctags/parsers/relaxng.c (revision 6b1a862e526d5017f9f212a321f59d67c859d521)
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