xref: /Universal-ctags/parsers/ant.c (revision 6b1a862e526d5017f9f212a321f59d67c859d521)
13ae02089SMasatake YAMATO /*
23ae02089SMasatake YAMATO *   Copyright (c) 2008, David Fishburn
33ae02089SMasatake YAMATO *
43ae02089SMasatake YAMATO *   This source code is released for free distribution under the terms of the
50ce38835Sviccuad *   GNU General Public License version 2 or (at your option) any later version.
63ae02089SMasatake YAMATO *
73ae02089SMasatake YAMATO *   This module contains functions for generating tags for Ant language files.
83ae02089SMasatake YAMATO */
93ae02089SMasatake YAMATO 
103ae02089SMasatake YAMATO /*
113ae02089SMasatake YAMATO *   INCLUDE FILES
123ae02089SMasatake YAMATO */
133ae02089SMasatake YAMATO #include "general.h"  /* must always come first */
143ae02089SMasatake YAMATO 
153ae02089SMasatake YAMATO #include <string.h>
1614781660SMasatake YAMATO #include "entry.h"
173ae02089SMasatake YAMATO #include "parse.h"
183db72c21SMasatake YAMATO #include "routines.h"
1962909b9dSMasatake YAMATO #ifdef HAVE_LIBXML
2062909b9dSMasatake YAMATO #include "read.h"
2162909b9dSMasatake YAMATO #include "selectors.h"
2283569be2SMasatake YAMATO #include "xml.h"
2362909b9dSMasatake YAMATO #endif
243ae02089SMasatake YAMATO 
2562909b9dSMasatake YAMATO #ifdef HAVE_LIBXML
2662909b9dSMasatake YAMATO /*
2762909b9dSMasatake YAMATO *   FUNCTION PROTOTYPES
2862909b9dSMasatake YAMATO */
2962909b9dSMasatake YAMATO static void antFindTagsUnderProject (xmlNode *node,
30513a7223SMasatake YAMATO 				     const char *xpath,
3162909b9dSMasatake YAMATO 				     const struct sTagXpathRecurSpec *spec,
3262909b9dSMasatake YAMATO 				     xmlXPathContext *ctx,
3362909b9dSMasatake YAMATO 				     void *userData);
3462909b9dSMasatake YAMATO static void antFindTagsUnderTask (xmlNode *node,
35513a7223SMasatake YAMATO 				  const char *xpath,
3662909b9dSMasatake YAMATO 				  const struct sTagXpathRecurSpec *spec,
3762909b9dSMasatake YAMATO 				  xmlXPathContext *ctx,
3862909b9dSMasatake YAMATO 				  void *userData);
3962909b9dSMasatake YAMATO static void makeTagForProjectName (xmlNode *node,
40513a7223SMasatake YAMATO 				   const char *xpath,
4162909b9dSMasatake YAMATO 				   const struct sTagXpathMakeTagSpec *spec,
4262909b9dSMasatake YAMATO 				   struct sTagEntryInfo *tag,
4362909b9dSMasatake YAMATO 				   void *userData);
4462909b9dSMasatake YAMATO static void makeTagForTargetName (xmlNode *node,
45513a7223SMasatake YAMATO 				  const char *xpath,
4662909b9dSMasatake YAMATO 				  const struct sTagXpathMakeTagSpec *spec,
4762909b9dSMasatake YAMATO 				  struct sTagEntryInfo *tag,
4862909b9dSMasatake YAMATO 				  void *userData);
4962909b9dSMasatake YAMATO static void makeTagWithScope (xmlNode *node,
50513a7223SMasatake YAMATO 				  const char *xpath,
5162909b9dSMasatake YAMATO 			      const struct sTagXpathMakeTagSpec *spec,
5262909b9dSMasatake YAMATO 			      struct sTagEntryInfo *tag,
5362909b9dSMasatake YAMATO 			      void *userData);
5462909b9dSMasatake YAMATO #endif
5562909b9dSMasatake YAMATO 
5662909b9dSMasatake YAMATO #ifdef HAVE_LIBXML
5762909b9dSMasatake YAMATO typedef enum {
5862909b9dSMasatake YAMATO 	K_PROJECT, K_TARGET, K_PROPERTY, K_IMPORT,
5962909b9dSMasatake YAMATO } antKind;
6062909b9dSMasatake YAMATO 
6162909b9dSMasatake YAMATO typedef enum {
6262909b9dSMasatake YAMATO 	R_IMPORT_GENERIC,
6362909b9dSMasatake YAMATO } antAntfileRole;
6462909b9dSMasatake YAMATO 
6513457258SMasatake YAMATO static roleDefinition AntAntfileRoles [] = {
66ce990805SThomas Braun         { true, "imported", "imported" },
6762909b9dSMasatake YAMATO };
6862909b9dSMasatake YAMATO 
69e112e8abSMasatake YAMATO static kindDefinition AntKinds [] = {
70ce990805SThomas Braun 	{ true,  'p', "project",  "projects"   },
71ce990805SThomas Braun 	{ true,  't', "target",   "targets"    },
72ce990805SThomas Braun 	{ true,  'P', "property", "properties(global)" },
73ce990805SThomas Braun 	{ true,  'i', "antfile",  "antfiles",
74ce990805SThomas Braun 	  .referenceOnly = true, ATTACH_ROLES(AntAntfileRoles)},
7562909b9dSMasatake YAMATO };
7662909b9dSMasatake YAMATO 
7762909b9dSMasatake YAMATO enum antXpathTable {
7862909b9dSMasatake YAMATO 	TABLE_MAIN, TABLE_PROJECT, TABLE_MAIN_NAME, TABLE_TARGET_NAME,
7962909b9dSMasatake YAMATO };
8062909b9dSMasatake YAMATO 
8162909b9dSMasatake YAMATO static tagXpathTable antXpathMainTable [] = {
8262909b9dSMasatake YAMATO 	{ "///project",
8362909b9dSMasatake YAMATO 	  LXPATH_TABLE_DO_RECUR,
84a9bb575fSMasatake YAMATO 	  { .recurSpec= { antFindTagsUnderProject } }
8562909b9dSMasatake YAMATO 	},
8662909b9dSMasatake YAMATO };
8762909b9dSMasatake YAMATO 
8862909b9dSMasatake YAMATO static tagXpathTable antXpathProjectTable [] = {
8962909b9dSMasatake YAMATO 	{ "target",
9062909b9dSMasatake YAMATO 	  LXPATH_TABLE_DO_RECUR,
918df526f3SMasatake YAMATO 	  { .recurSpec= { antFindTagsUnderTask, TABLE_TARGET_NAME } }
9262909b9dSMasatake YAMATO 	},
9362909b9dSMasatake YAMATO 	{ "property/@name",
9462909b9dSMasatake YAMATO 	  LXPATH_TABLE_DO_MAKE,
9524b256e3SMasatake YAMATO 	  { .makeTagSpec = { K_PROPERTY, ROLE_DEFINITION_INDEX,
96a9bb575fSMasatake YAMATO 			     makeTagWithScope } }
9762909b9dSMasatake YAMATO 	},
9862909b9dSMasatake YAMATO 	{ "import/@file",
9962909b9dSMasatake YAMATO 	  LXPATH_TABLE_DO_MAKE,
100a9bb575fSMasatake YAMATO 	  { .makeTagSpec = { K_IMPORT, R_IMPORT_GENERIC,
101a9bb575fSMasatake YAMATO 			     makeTagWithScope } }
10262909b9dSMasatake YAMATO 	},
10362909b9dSMasatake YAMATO };
10462909b9dSMasatake YAMATO 
10562909b9dSMasatake YAMATO static tagXpathTable antXpathMainNameTable [] = {
10662909b9dSMasatake YAMATO 	{ "@name",
10762909b9dSMasatake YAMATO 	  LXPATH_TABLE_DO_MAKE,
10824b256e3SMasatake YAMATO 	  { .makeTagSpec = { K_PROJECT, ROLE_DEFINITION_INDEX,
109a9bb575fSMasatake YAMATO 			     makeTagForProjectName } }
11062909b9dSMasatake YAMATO 	},
11162909b9dSMasatake YAMATO };
11262909b9dSMasatake YAMATO 
11362909b9dSMasatake YAMATO static tagXpathTable antXpathTargetNameTable [] = {
11462909b9dSMasatake YAMATO 	{ "@name",
11562909b9dSMasatake YAMATO 	  LXPATH_TABLE_DO_MAKE,
11624b256e3SMasatake YAMATO 	  { .makeTagSpec = { K_TARGET, ROLE_DEFINITION_INDEX,
117a9bb575fSMasatake YAMATO 			     makeTagForTargetName} }
11862909b9dSMasatake YAMATO 	},
11962909b9dSMasatake YAMATO };
12062909b9dSMasatake YAMATO 
12162909b9dSMasatake YAMATO static tagXpathTableTable antXpathTableTable[] = {
12262909b9dSMasatake YAMATO 	[TABLE_MAIN]        = { ARRAY_AND_SIZE (antXpathMainTable)       },
12362909b9dSMasatake YAMATO 	[TABLE_PROJECT]     = { ARRAY_AND_SIZE (antXpathProjectTable)    },
12462909b9dSMasatake YAMATO 	[TABLE_MAIN_NAME]   = { ARRAY_AND_SIZE (antXpathMainNameTable)   },
12562909b9dSMasatake YAMATO 	[TABLE_TARGET_NAME] = { ARRAY_AND_SIZE (antXpathTargetNameTable) },
12662909b9dSMasatake YAMATO };
12762909b9dSMasatake YAMATO 
12862909b9dSMasatake YAMATO #else
1299a44473dSMasatake YAMATO static tagRegexTable antTagRegexTable [] = {
130dc0f490fSMasatake YAMATO 	{"^[ \t]*<[ \t]*project[^>]+name=\"([^\"]+)\".*", "\\1",
131dc0f490fSMasatake YAMATO 	 "p,project,projects", NULL},
132dc0f490fSMasatake YAMATO 	{"^[ \t]*<[ \t]*target[^>]+name=\"([^\"]+)\".*", "\\1",
133dc0f490fSMasatake YAMATO 	 "t,target,targets", NULL},
134dc0f490fSMasatake YAMATO 	{"^[ \t]*<[ \t]*property[^>]+name=\"([^\"]+)\".*", "\\1",
135dc0f490fSMasatake YAMATO 	 "P,property,property", NULL},
136dc0f490fSMasatake YAMATO };
13762909b9dSMasatake YAMATO #endif
138dc0f490fSMasatake YAMATO 
1393ae02089SMasatake YAMATO /*
1403ae02089SMasatake YAMATO *   FUNCTION DEFINITIONS
1413ae02089SMasatake YAMATO */
14262909b9dSMasatake YAMATO #ifdef HAVE_LIBXML
14362909b9dSMasatake YAMATO 
14462909b9dSMasatake YAMATO static void
antFindTagsUnderProject(xmlNode * node,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathRecurSpec * spec CTAGS_ATTR_UNUSED,xmlXPathContext * ctx,void * userData CTAGS_ATTR_UNUSED)14562909b9dSMasatake YAMATO antFindTagsUnderProject (xmlNode *node,
146513a7223SMasatake YAMATO 			 const char *xpath CTAGS_ATTR_UNUSED,
1478ccb7ee9SJiří Techet 			 const struct sTagXpathRecurSpec *spec CTAGS_ATTR_UNUSED,
14862909b9dSMasatake YAMATO 			 xmlXPathContext *ctx,
1498ccb7ee9SJiří Techet 			 void *userData CTAGS_ATTR_UNUSED)
15062909b9dSMasatake YAMATO {
151f6027918SMasatake YAMATO 	int corkIndex = CORK_NIL;
15262909b9dSMasatake YAMATO 
153971e7196SMasatake YAMATO 	findXMLTags (ctx, node, TABLE_MAIN_NAME, &corkIndex);
154971e7196SMasatake YAMATO 	findXMLTags (ctx, node, TABLE_PROJECT, &corkIndex);
15562909b9dSMasatake YAMATO }
15662909b9dSMasatake YAMATO 
antFindTagsUnderTask(xmlNode * node,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathRecurSpec * spec,xmlXPathContext * ctx,void * userData)15762909b9dSMasatake YAMATO static void antFindTagsUnderTask (xmlNode *node,
158513a7223SMasatake YAMATO 				  const char *xpath CTAGS_ATTR_UNUSED,
1598df526f3SMasatake YAMATO 				  const struct sTagXpathRecurSpec *spec,
16062909b9dSMasatake YAMATO 				  xmlXPathContext *ctx,
16162909b9dSMasatake YAMATO 				  void *userData)
16262909b9dSMasatake YAMATO {
16362909b9dSMasatake YAMATO 	int corkIndex = *(int *)userData;
16462909b9dSMasatake YAMATO 
165971e7196SMasatake YAMATO 	findXMLTags (ctx, node, spec->nextTable, &corkIndex);
16662909b9dSMasatake YAMATO }
16762909b9dSMasatake YAMATO 
makeTagForProjectName(xmlNode * node CTAGS_ATTR_UNUSED,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathMakeTagSpec * spec CTAGS_ATTR_UNUSED,struct sTagEntryInfo * tag,void * userData)1688ccb7ee9SJiří Techet static void makeTagForProjectName (xmlNode *node CTAGS_ATTR_UNUSED,
169513a7223SMasatake YAMATO 				   const char *xpath CTAGS_ATTR_UNUSED,
1708ccb7ee9SJiří Techet 				   const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,
17162909b9dSMasatake YAMATO 				   struct sTagEntryInfo *tag,
17262909b9dSMasatake YAMATO 				   void *userData)
17362909b9dSMasatake YAMATO {
17462909b9dSMasatake YAMATO 	int *corkIndex = userData;
17562909b9dSMasatake YAMATO 
17662909b9dSMasatake YAMATO 	*corkIndex = makeTagEntry (tag);
17762909b9dSMasatake YAMATO }
17862909b9dSMasatake YAMATO 
makeTagForTargetName(xmlNode * node CTAGS_ATTR_UNUSED,const char * xpath CTAGS_ATTR_UNUSED,const struct sTagXpathMakeTagSpec * spec CTAGS_ATTR_UNUSED,struct sTagEntryInfo * tag,void * userData)1798ccb7ee9SJiří Techet static void makeTagForTargetName (xmlNode *node CTAGS_ATTR_UNUSED,
180513a7223SMasatake YAMATO 				  const char *xpath CTAGS_ATTR_UNUSED,
1818ccb7ee9SJiří Techet 				  const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,
18262909b9dSMasatake YAMATO 				  struct sTagEntryInfo *tag,
18362909b9dSMasatake YAMATO 				  void *userData)
18462909b9dSMasatake YAMATO {
18562909b9dSMasatake YAMATO 	int *corkIndex = (int *)userData;
18662909b9dSMasatake YAMATO 	int parentIndex = *corkIndex;
18762909b9dSMasatake YAMATO 
188f92e6bf2SMasatake YAMATO 	tag->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;
18962909b9dSMasatake YAMATO 	tag->extensionFields.scopeName  = NULL;
19062909b9dSMasatake YAMATO 	tag->extensionFields.scopeIndex = parentIndex;
19162909b9dSMasatake YAMATO 
19262909b9dSMasatake YAMATO 	*corkIndex = makeTagEntry (tag);
19362909b9dSMasatake YAMATO }
19462909b9dSMasatake 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)1958ccb7ee9SJiří Techet static void makeTagWithScope (xmlNode *node CTAGS_ATTR_UNUSED,
196513a7223SMasatake YAMATO 			      const char *xpath CTAGS_ATTR_UNUSED,
1978ccb7ee9SJiří Techet 			      const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,
19862909b9dSMasatake YAMATO 			      struct sTagEntryInfo *tag,
19962909b9dSMasatake YAMATO 			      void *userData)
20062909b9dSMasatake YAMATO {
201f92e6bf2SMasatake YAMATO 	tag->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;
20262909b9dSMasatake YAMATO 	tag->extensionFields.scopeName  = NULL;
20362909b9dSMasatake YAMATO 	tag->extensionFields.scopeIndex = *(int *)userData;
20462909b9dSMasatake YAMATO 
20562909b9dSMasatake YAMATO 	makeTagEntry (tag);
20662909b9dSMasatake YAMATO }
20762909b9dSMasatake YAMATO 
20862909b9dSMasatake YAMATO static void
findAntTags(void)20962909b9dSMasatake YAMATO findAntTags (void)
21062909b9dSMasatake YAMATO {
21183569be2SMasatake YAMATO 	scheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);
21262909b9dSMasatake YAMATO }
21383569be2SMasatake YAMATO 
21483569be2SMasatake YAMATO static void
runXPathEngine(xmlSubparser * s,xmlXPathContext * ctx,xmlNode * root)21583569be2SMasatake YAMATO runXPathEngine(xmlSubparser *s,
21683569be2SMasatake YAMATO 			   xmlXPathContext *ctx, xmlNode *root)
21783569be2SMasatake YAMATO {
21883569be2SMasatake YAMATO 	findXMLTags (ctx, root, TABLE_MAIN, NULL);
21983569be2SMasatake YAMATO }
22083569be2SMasatake YAMATO 
22183569be2SMasatake YAMATO static xmlSubparser antSubparser = {
22283569be2SMasatake YAMATO 	.subparser = {
22383569be2SMasatake YAMATO 		.direction = SUBPARSER_BI_DIRECTION,
22483569be2SMasatake YAMATO 	},
22583569be2SMasatake YAMATO 	.runXPathEngine = runXPathEngine,
22683569be2SMasatake YAMATO };
22762909b9dSMasatake YAMATO #endif
2283ae02089SMasatake YAMATO 
AntParser(void)2293ae02089SMasatake YAMATO extern parserDefinition* AntParser (void)
2303ae02089SMasatake YAMATO {
23162909b9dSMasatake YAMATO 	static const char *const extensions [] = { "build.xml", "ant",
23262909b9dSMasatake YAMATO #ifdef HAVE_LIBXML
23362909b9dSMasatake YAMATO 				/* libxml based selector is needed to select a
23462909b9dSMasatake YAMATO 				 * proper concrete xml parser.*/
23562909b9dSMasatake YAMATO 						   "xml",
23662909b9dSMasatake YAMATO #endif
23762909b9dSMasatake YAMATO 						   NULL };
2383ae02089SMasatake YAMATO 	static const char *const patterns [] = { "build.xml", NULL };
2393ae02089SMasatake YAMATO 	parserDefinition* const def = parserNew ("Ant");
24062909b9dSMasatake YAMATO #ifdef HAVE_LIBXML
241ff522ef8SMasatake YAMATO 	static selectLanguage selectors[] = { selectByXpathFileSpec, NULL };
2427fcb59fbSMasatake YAMATO 	static xpathFileSpec xpathFileSpecs[] = {
2437fcb59fbSMasatake YAMATO 		/* See http://ant.apache.org/faq.html#dtd */
2447fcb59fbSMasatake YAMATO 		{
2457fcb59fbSMasatake YAMATO 			.rootElementName = "project",
2467fcb59fbSMasatake YAMATO 			.nameInDTD       = "",
2477fcb59fbSMasatake YAMATO 			.externalID      = "",
2487fcb59fbSMasatake YAMATO 			.systemID        = "",
2497fcb59fbSMasatake YAMATO 			.rootNSPrefix    = "",
2507fcb59fbSMasatake YAMATO 			.rootNSHref      = "",
2517fcb59fbSMasatake YAMATO 		},
2527fcb59fbSMasatake YAMATO 		{
2537fcb59fbSMasatake YAMATO 			.rootElementName = "project",
2547fcb59fbSMasatake YAMATO 			.nameInDTD       = "project",
2557fcb59fbSMasatake YAMATO 			.externalID      = "",
2567fcb59fbSMasatake YAMATO 			.systemID        = "",
2577fcb59fbSMasatake YAMATO 			.rootNSPrefix    = "",
2587fcb59fbSMasatake YAMATO 			.rootNSHref      = "",
2597fcb59fbSMasatake YAMATO 		}
2607fcb59fbSMasatake YAMATO 	};
26183569be2SMasatake YAMATO 	static parserDependency dependencies [] = {
26283569be2SMasatake YAMATO 		[0] = { DEPTYPE_SUBPARSER, "XML", &antSubparser },
26383569be2SMasatake YAMATO 	};
26462909b9dSMasatake YAMATO #endif
2653ae02089SMasatake YAMATO 	def->extensions = extensions;
2663ae02089SMasatake YAMATO 	def->patterns = patterns;
26762909b9dSMasatake YAMATO #ifdef HAVE_LIBXML
26809ae690fSMasatake YAMATO 	def->kindTable = AntKinds;
26962909b9dSMasatake YAMATO 	def->kindCount = ARRAY_SIZE (AntKinds);
27062909b9dSMasatake YAMATO 	def->parser = findAntTags;
27162909b9dSMasatake YAMATO 	def->tagXpathTableTable = antXpathTableTable;
27262909b9dSMasatake YAMATO 	def->tagXpathTableCount = ARRAY_SIZE (antXpathTableTable);
273*6b1a862eSMasatake YAMATO 	def->useCork = CORK_QUEUE;
27462909b9dSMasatake YAMATO 	def->selectLanguage = selectors;
2757fcb59fbSMasatake YAMATO 	def->xpathFileSpecs = xpathFileSpecs;
2767fcb59fbSMasatake YAMATO 	def->xpathFileSpecCount = ARRAY_SIZE (xpathFileSpecs);
27783569be2SMasatake YAMATO 	def->dependencies = dependencies;
27883569be2SMasatake YAMATO 	def->dependencyCount = ARRAY_SIZE (dependencies);
27962909b9dSMasatake YAMATO #else
280dc0f490fSMasatake YAMATO 	def->tagRegexTable = antTagRegexTable;
2813db72c21SMasatake YAMATO 	def->tagRegexCount = ARRAY_SIZE (antTagRegexTable);
2823ae02089SMasatake YAMATO 	def->method     = METHOD_NOT_CRAFTED|METHOD_REGEX;
28362909b9dSMasatake YAMATO #endif
2843ae02089SMasatake YAMATO 	return def;
2853ae02089SMasatake YAMATO }
286