xref: /Universal-ctags/parsers/automake.c (revision be440f85f3708cf0f2deb40928355d50ccc05d40)
1bee78c38SMasatake YAMATO /*
2bee78c38SMasatake YAMATO *   Copyright (c) 2000-2005, Darren Hiebert
3bee78c38SMasatake YAMATO *
4bee78c38SMasatake YAMATO *   This source code is released for free distribution under the terms of the
5bee78c38SMasatake YAMATO *   GNU General Public License version 2 or (at your option) any later version.
6bee78c38SMasatake YAMATO *
7bee78c38SMasatake YAMATO *   This module contains functions for generating tags for makefiles.
8bee78c38SMasatake YAMATO */
9bee78c38SMasatake YAMATO 
10bee78c38SMasatake YAMATO /*
11bee78c38SMasatake YAMATO *   INCLUDE FILES
12bee78c38SMasatake YAMATO */
13bee78c38SMasatake YAMATO #include "general.h"  /* must always come first */
14bee78c38SMasatake YAMATO 
15bee78c38SMasatake YAMATO #include <string.h>
16bee78c38SMasatake YAMATO #include <ctype.h>
17bee78c38SMasatake YAMATO 
1887214e15SMasatake YAMATO #include "make.h"
19bee78c38SMasatake YAMATO 
20bee78c38SMasatake YAMATO #include "entry.h"
21bee78c38SMasatake YAMATO #include "htable.h"
22bee78c38SMasatake YAMATO #include "kind.h"
23bee78c38SMasatake YAMATO #include "parse.h"
24bee78c38SMasatake YAMATO #include "read.h"
25c70c75f4SMasatake YAMATO #include "subparser.h"
26bee78c38SMasatake YAMATO 
27bee78c38SMasatake YAMATO 
28bee78c38SMasatake YAMATO typedef enum {
29bee78c38SMasatake YAMATO 	K_AM_DIR,
30bee78c38SMasatake YAMATO 	K_AM_PROGRAM,
31bee78c38SMasatake YAMATO 	K_AM_MAN,
32bee78c38SMasatake YAMATO 	K_AM_LTLIBRARY,
33bee78c38SMasatake YAMATO 	K_AM_LIBRARY,
34bee78c38SMasatake YAMATO 	K_AM_SCRIPT,
35bee78c38SMasatake YAMATO 	K_AM_DATA,
36bee78c38SMasatake YAMATO 	K_AM_CONDITION,
37b245a051SMasatake YAMATO 	K_AM_SUBDIR,
38bee78c38SMasatake YAMATO } makeAMKind;
39bee78c38SMasatake YAMATO 
40bee78c38SMasatake YAMATO typedef enum {
41bee78c38SMasatake YAMATO 	R_AM_DIR_PROGRAMS,
42bee78c38SMasatake YAMATO 	R_AM_DIR_MANS,
43bee78c38SMasatake YAMATO 	R_AM_DIR_LTLIBRARIES,
44bee78c38SMasatake YAMATO 	R_AM_DIR_LIBRARIES,
45bee78c38SMasatake YAMATO 	R_AM_DIR_SCRIPTS,
46bee78c38SMasatake YAMATO 	R_AM_DIR_DATA,
47bee78c38SMasatake YAMATO } makeAMDirectoryRole;
48bee78c38SMasatake YAMATO 
4913457258SMasatake YAMATO static roleDefinition AutomakeDirectoryRoles [] = {
50ce990805SThomas Braun 	{ true, "program",   "directory for PROGRAMS primary" },
51ce990805SThomas Braun 	{ true, "man",       "directory for MANS primary" },
52ce990805SThomas Braun 	{ true, "ltlibrary", "directory for LTLIBRARIES primary"},
53ce990805SThomas Braun 	{ true, "library",   "directory for LIBRARIES primary"},
54ce990805SThomas Braun 	{ true, "script",    "directory for SCRIPTS primary"},
55ce990805SThomas Braun 	{ true, "data",      "directory for DATA primary"},
56bee78c38SMasatake YAMATO };
57bee78c38SMasatake YAMATO 
58bee78c38SMasatake YAMATO typedef enum {
59bee78c38SMasatake YAMATO 	R_AM_CONDITION_BRANCHED,
60bee78c38SMasatake YAMATO } makeAMConditionRole;
61bee78c38SMasatake YAMATO 
6213457258SMasatake YAMATO static roleDefinition AutomakeConditionRoles [] = {
63ce990805SThomas Braun 	{ true, "branched",  "used for branching" },
64bee78c38SMasatake YAMATO };
65bee78c38SMasatake YAMATO 
66bee78c38SMasatake YAMATO static scopeSeparator AutomakeSeparators [] = {
67f92e6bf2SMasatake YAMATO 	{ K_AM_DIR        , "/" },
68bee78c38SMasatake YAMATO };
69bee78c38SMasatake YAMATO 
70e112e8abSMasatake YAMATO static kindDefinition AutomakeKinds [] = {
71ce990805SThomas Braun 	{ true, 'd', "directory", "directories",
72ce990805SThomas Braun 	  .referenceOnly = false, ATTACH_ROLES(AutomakeDirectoryRoles)},
73ce990805SThomas Braun 	{ true, 'P', "program",   "programs",
74bee78c38SMasatake YAMATO 	  ATTACH_SEPARATORS(AutomakeSeparators) },
75ce990805SThomas Braun 	{ true, 'M', "man",       "manuals",
76bee78c38SMasatake YAMATO 	  ATTACH_SEPARATORS(AutomakeSeparators) },
77ce990805SThomas Braun 	{ true, 'T', "ltlibrary", "ltlibraries",
78bee78c38SMasatake YAMATO 	  ATTACH_SEPARATORS(AutomakeSeparators) },
79ce990805SThomas Braun 	{ true, 'L', "library",   "libraries",
80bee78c38SMasatake YAMATO 	  ATTACH_SEPARATORS(AutomakeSeparators) },
81ce990805SThomas Braun 	{ true, 'S', "script",    "scripts",
82bee78c38SMasatake YAMATO 	  ATTACH_SEPARATORS(AutomakeSeparators) },
83ce990805SThomas Braun 	{ true, 'D', "data",      "datum",
84bee78c38SMasatake YAMATO 	  ATTACH_SEPARATORS(AutomakeSeparators) },
85ce990805SThomas Braun 	{ true, 'c', "condition", "conditions",
86ce990805SThomas Braun 	  .referenceOnly = true, ATTACH_ROLES(AutomakeConditionRoles) },
87b245a051SMasatake YAMATO 	{ true, 's', "subdir", "subdirs" },
88bee78c38SMasatake YAMATO };
89bee78c38SMasatake YAMATO 
90bee78c38SMasatake YAMATO struct sBlacklist {
91bee78c38SMasatake YAMATO 	enum { BL_END, BL_PREFIX } type;
92bee78c38SMasatake YAMATO 	const char* substr;
93bee78c38SMasatake YAMATO 	size_t len;
94bee78c38SMasatake YAMATO } am_blacklist [] = {
95bee78c38SMasatake YAMATO 	{ BL_PREFIX, "EXTRA",  5 },
96bee78c38SMasatake YAMATO 	{ BL_PREFIX, "noinst", 6 },
97bee78c38SMasatake YAMATO 	{ BL_PREFIX, "check",  5 },
98bee78c38SMasatake YAMATO 	{ BL_END,    NULL,     0 },
99bee78c38SMasatake YAMATO };
100bee78c38SMasatake YAMATO 
101c70c75f4SMasatake YAMATO struct sAutomakeSubparser {
102c70c75f4SMasatake YAMATO 	makeSubparser make;
103c70c75f4SMasatake YAMATO 
104c70c75f4SMasatake YAMATO 	hashTable* directories;
105c70c75f4SMasatake YAMATO 	int index;
106b245a051SMasatake YAMATO 	bool in_subdirs;
107c70c75f4SMasatake YAMATO };
108c70c75f4SMasatake YAMATO 
109bee78c38SMasatake YAMATO 
bl_check(const char * name,struct sBlacklist * blacklist)110ce990805SThomas Braun static bool bl_check (const char *name, struct sBlacklist *blacklist)
111bee78c38SMasatake YAMATO {
112bee78c38SMasatake YAMATO 	if ((blacklist->type == BL_PREFIX) &&
113bee78c38SMasatake YAMATO 	    (strncmp (blacklist->substr, name, blacklist->len) == 0))
114ce990805SThomas Braun 		return false;
115bee78c38SMasatake YAMATO 	else
116ce990805SThomas Braun 		return true;
117bee78c38SMasatake YAMATO }
118bee78c38SMasatake YAMATO 
lookupAutomakeDirectory(hashTable * directories,vString * const name)119c70c75f4SMasatake YAMATO static int lookupAutomakeDirectory (hashTable* directories,  vString *const name)
120bee78c38SMasatake YAMATO {
121c70c75f4SMasatake YAMATO 	int *i = hashTableGetItem (directories,  vStringValue (name));
122bee78c38SMasatake YAMATO 
123bee78c38SMasatake YAMATO 	if (i)
124bee78c38SMasatake YAMATO 		return *i;
125bee78c38SMasatake YAMATO 	else
126bee78c38SMasatake YAMATO 		return CORK_NIL;
127bee78c38SMasatake YAMATO }
128bee78c38SMasatake YAMATO 
addAutomakeDirectory(hashTable * directories,vString * const name,int corkIndex)129c70c75f4SMasatake YAMATO static void addAutomakeDirectory (hashTable* directories, vString *const name, int corkIndex)
130bee78c38SMasatake YAMATO {
131f270909bSMasatake YAMATO 	char * k = vStringStrdup (name);
132bee78c38SMasatake YAMATO 	int  * i = xMalloc (1, int);
133bee78c38SMasatake YAMATO 
134bee78c38SMasatake YAMATO 	*i = corkIndex;
135bee78c38SMasatake YAMATO 
136c70c75f4SMasatake YAMATO 	hashTablePutItem (directories, k, i);
137bee78c38SMasatake YAMATO }
138bee78c38SMasatake YAMATO 
automakeMakeTag(struct sAutomakeSubparser * automake,char * name,const char * suffix,bool appending,int kindex,int rindex,struct sBlacklist * blacklist)139c70c75f4SMasatake YAMATO static bool automakeMakeTag (struct sAutomakeSubparser* automake,
140c70c75f4SMasatake YAMATO 							 char* name, const char* suffix, bool appending,
141c70c75f4SMasatake YAMATO 							 int kindex, int rindex, struct sBlacklist *blacklist)
142bee78c38SMasatake YAMATO {
143bee78c38SMasatake YAMATO 	size_t expected_len;
144bee78c38SMasatake YAMATO 	size_t len;
145bee78c38SMasatake YAMATO 	char* tail;
146bee78c38SMasatake YAMATO 	vString *subname;
147bee78c38SMasatake YAMATO 	int i;
148bee78c38SMasatake YAMATO 
149c70c75f4SMasatake YAMATO 	len = strlen (name);
150bee78c38SMasatake YAMATO 	expected_len = strlen (suffix);
151bee78c38SMasatake YAMATO 
152bee78c38SMasatake YAMATO 	if (len <= expected_len)
153ce990805SThomas Braun 		return false;
154bee78c38SMasatake YAMATO 
155bee78c38SMasatake YAMATO 	for (i = 0; blacklist[i].type != BL_END; i++)
156bee78c38SMasatake YAMATO 	{
157c70c75f4SMasatake YAMATO 		if (bl_check (name, blacklist + i) == false)
158ce990805SThomas Braun 			return false;
159bee78c38SMasatake YAMATO 	}
160bee78c38SMasatake YAMATO 
161c70c75f4SMasatake YAMATO 	tail = name + len - expected_len;
162bee78c38SMasatake YAMATO 	if (strcmp (tail, suffix))
163ce990805SThomas Braun 		return false;
164bee78c38SMasatake YAMATO 
165bee78c38SMasatake YAMATO 	subname = vStringNew();
166bee78c38SMasatake YAMATO 
167bee78c38SMasatake YAMATO 	/* ??? dist, nodist, nobase, notrans,... */
168c70c75f4SMasatake YAMATO 	if (strncmp (name, "dist_", 5) == 0)
169c70c75f4SMasatake YAMATO 		vStringNCopyS(subname, name + 5, len - expected_len - 5);
170bee78c38SMasatake YAMATO 	else
171c70c75f4SMasatake YAMATO 		vStringNCopyS(subname, name, len - expected_len);
172bee78c38SMasatake YAMATO 
17324b256e3SMasatake YAMATO 	if (rindex == ROLE_DEFINITION_INDEX)
174bee78c38SMasatake YAMATO 	{
17516a2541cSMasatake YAMATO 		automake->index = makeSimpleTag (subname, kindex);
176c70c75f4SMasatake YAMATO 		addAutomakeDirectory (automake->directories, subname, automake->index);
177bee78c38SMasatake YAMATO 	}
178bee78c38SMasatake YAMATO 	else
179bee78c38SMasatake YAMATO 	{
180c70c75f4SMasatake YAMATO 		automake->index = CORK_NIL;
181bee78c38SMasatake YAMATO 		if (appending)
182c70c75f4SMasatake YAMATO 			automake->index = lookupAutomakeDirectory (automake->directories, subname);
183bee78c38SMasatake YAMATO 
184c70c75f4SMasatake YAMATO 		if ((!appending) || (automake->index == CORK_NIL))
18516a2541cSMasatake YAMATO 			automake->index = makeSimpleRefTag (subname, kindex, rindex);
186bee78c38SMasatake YAMATO 	}
187bee78c38SMasatake YAMATO 
188bee78c38SMasatake YAMATO 	vStringDelete (subname);
189ce990805SThomas Braun 	return true;
190bee78c38SMasatake YAMATO }
191bee78c38SMasatake YAMATO 
valueCallback(makeSubparser * make,char * name)192c70c75f4SMasatake YAMATO static void valueCallback (makeSubparser *make, char *name)
193bee78c38SMasatake YAMATO {
194c70c75f4SMasatake YAMATO 	struct sAutomakeSubparser *automake = (struct sAutomakeSubparser *)make;
195c70c75f4SMasatake YAMATO 	int p = automake->index;
196bee78c38SMasatake YAMATO 	tagEntryInfo *parent;
197bee78c38SMasatake YAMATO 	int k;
198bee78c38SMasatake YAMATO 	tagEntryInfo elt;
199bee78c38SMasatake YAMATO 
200bee78c38SMasatake YAMATO 	parent = getEntryInCorkQueue (p);
2013671ad72SMasatake YAMATO 	if (parent && (parent->kindIndex == K_AM_DIR)
2029062cbc8SMasatake YAMATO 	    && (parent->extensionFields.roleBits))
203bee78c38SMasatake YAMATO 	{
2049062cbc8SMasatake YAMATO 		int roleIndex;
2059062cbc8SMasatake YAMATO 		for (roleIndex = 0; roleIndex < ARRAY_SIZE(AutomakeDirectoryRoles); roleIndex++)
2069062cbc8SMasatake YAMATO 			if (parent->extensionFields.roleBits & ((roleBitsType)1) << roleIndex)
2079062cbc8SMasatake YAMATO 				break;
2089062cbc8SMasatake YAMATO 
2099062cbc8SMasatake YAMATO 		k = K_AM_PROGRAM + roleIndex;
21016a2541cSMasatake YAMATO 		initTagEntry (&elt, name, k);
211bee78c38SMasatake YAMATO 		elt.extensionFields.scopeIndex = p;
212bee78c38SMasatake YAMATO 		makeTagEntry (&elt);
213bee78c38SMasatake YAMATO 	}
214b245a051SMasatake YAMATO 	else if (automake->in_subdirs)
215b245a051SMasatake YAMATO 	{
216b245a051SMasatake YAMATO 		initTagEntry (&elt, name, K_AM_SUBDIR);
217b245a051SMasatake YAMATO 		makeTagEntry (&elt);
218b245a051SMasatake YAMATO 	}
219bee78c38SMasatake YAMATO }
220bee78c38SMasatake YAMATO 
refCondtionAM(vString * directive)221bee78c38SMasatake YAMATO static void refCondtionAM (vString *directive)
222bee78c38SMasatake YAMATO {
22316a2541cSMasatake YAMATO 	makeSimpleRefTag (directive,
224bee78c38SMasatake YAMATO 			  K_AM_CONDITION, R_AM_CONDITION_BRANCHED);
225bee78c38SMasatake YAMATO }
226bee78c38SMasatake YAMATO 
nextChar(void)227bee78c38SMasatake YAMATO static int nextChar (void)
228bee78c38SMasatake YAMATO {
229bee78c38SMasatake YAMATO 	int c = getcFromInputFile ();
230bee78c38SMasatake YAMATO 	if (c == '\\')
231bee78c38SMasatake YAMATO 	{
232bee78c38SMasatake YAMATO 		c = getcFromInputFile ();
233bee78c38SMasatake YAMATO 		if (c == '\n')
234bee78c38SMasatake YAMATO 			c = nextChar ();
235bee78c38SMasatake YAMATO 	}
236bee78c38SMasatake YAMATO 	return c;
237bee78c38SMasatake YAMATO }
238bee78c38SMasatake YAMATO 
skipToNonWhite(int c)239bee78c38SMasatake YAMATO static int skipToNonWhite (int c)
240bee78c38SMasatake YAMATO {
241bee78c38SMasatake YAMATO 	while (c != '\n' && isspace (c))
242bee78c38SMasatake YAMATO 		c = nextChar ();
243bee78c38SMasatake YAMATO 	return c;
244bee78c38SMasatake YAMATO }
245bee78c38SMasatake YAMATO 
directiveCallback(makeSubparser * make CTAGS_ATTR_UNUSED,char * directive)246e4d16241SMasatake YAMATO static void directiveCallback (makeSubparser *make CTAGS_ATTR_UNUSED, char *directive)
247bee78c38SMasatake YAMATO {
248bee78c38SMasatake YAMATO 	int c;
249c70c75f4SMasatake YAMATO 	if (! strcmp (directive, "if"))
250bee78c38SMasatake YAMATO 	{
251bee78c38SMasatake YAMATO 		vString *condition = vStringNew ();
252bee78c38SMasatake YAMATO 
253bee78c38SMasatake YAMATO 		c = skipToNonWhite (nextChar ());
254bee78c38SMasatake YAMATO 		while (c != EOF && c != '\n')
255bee78c38SMasatake YAMATO 		{
256bee78c38SMasatake YAMATO 			/* the operator for negation should not be
257bee78c38SMasatake YAMATO 			   part of the condition name. */
258bee78c38SMasatake YAMATO 			if (c != '!')
259bee78c38SMasatake YAMATO 				vStringPut (condition, c);
260bee78c38SMasatake YAMATO 			c = nextChar ();
261bee78c38SMasatake YAMATO 		}
262bee78c38SMasatake YAMATO 		if (c == '\n')
263bee78c38SMasatake YAMATO 			ungetcToInputFile (c);
264bee78c38SMasatake YAMATO 		vStringStripTrailing (condition);
265bee78c38SMasatake YAMATO 		if (vStringLength (condition) > 0 )
266bee78c38SMasatake YAMATO 			refCondtionAM (condition);
267bee78c38SMasatake YAMATO 		vStringDelete (condition);
268bee78c38SMasatake YAMATO 	}
269bee78c38SMasatake YAMATO }
270bee78c38SMasatake YAMATO 
newMacroCallback(makeSubparser * make,char * name,bool with_define_directive,bool appending)271c70c75f4SMasatake YAMATO static void newMacroCallback (makeSubparser *make, char* name, bool with_define_directive,
272c70c75f4SMasatake YAMATO 							  bool appending)
273bee78c38SMasatake YAMATO {
274c70c75f4SMasatake YAMATO 	struct sAutomakeSubparser *automake = (struct sAutomakeSubparser *)make;
275c70c75f4SMasatake YAMATO 
276c70c75f4SMasatake YAMATO 	automake->index = CORK_NIL;
277b245a051SMasatake YAMATO 	automake->in_subdirs = false;
278bee78c38SMasatake YAMATO 
279bee78c38SMasatake YAMATO 	if (with_define_directive)
280bee78c38SMasatake YAMATO 		return;
281bee78c38SMasatake YAMATO 
282b245a051SMasatake YAMATO 	if (strcmp (name, "SUBDIRS") == 0)
283b245a051SMasatake YAMATO 	{
284b245a051SMasatake YAMATO 		automake->in_subdirs = true;
285b245a051SMasatake YAMATO 		return;
286b245a051SMasatake YAMATO 	}
287b245a051SMasatake YAMATO 
288bee78c38SMasatake YAMATO 	(void)(0
289c70c75f4SMasatake YAMATO 	       || automakeMakeTag (automake,
290c70c75f4SMasatake YAMATO 							   name, "dir", appending,
29124b256e3SMasatake YAMATO 							   K_AM_DIR, ROLE_DEFINITION_INDEX, am_blacklist)
292c70c75f4SMasatake YAMATO 	       || automakeMakeTag (automake,
293c70c75f4SMasatake YAMATO 							   name, "_PROGRAMS", appending,
294c70c75f4SMasatake YAMATO 							   K_AM_DIR, R_AM_DIR_PROGRAMS, am_blacklist)
295c70c75f4SMasatake YAMATO 	       || automakeMakeTag (automake,
296c70c75f4SMasatake YAMATO 							   name, "_MANS", appending,
297c70c75f4SMasatake YAMATO 							   K_AM_DIR, R_AM_DIR_MANS, am_blacklist)
298c70c75f4SMasatake YAMATO 	       || automakeMakeTag (automake,
299c70c75f4SMasatake YAMATO 							   name, "_LTLIBRARIES", appending,
300c70c75f4SMasatake YAMATO 							   K_AM_DIR, R_AM_DIR_LTLIBRARIES, am_blacklist)
301c70c75f4SMasatake YAMATO 	       || automakeMakeTag (automake,
302c70c75f4SMasatake YAMATO 							   name, "_LIBRARIES", appending,
303c70c75f4SMasatake YAMATO 							   K_AM_DIR, R_AM_DIR_LIBRARIES, am_blacklist)
304c70c75f4SMasatake YAMATO 	       || automakeMakeTag (automake,
305c70c75f4SMasatake YAMATO 							   name, "_SCRIPTS", appending,
306c70c75f4SMasatake YAMATO 							   K_AM_DIR, R_AM_DIR_SCRIPTS, am_blacklist)
307c70c75f4SMasatake YAMATO 	       || automakeMakeTag  (automake,
308c70c75f4SMasatake YAMATO 								name, "_DATA", appending,
309c70c75f4SMasatake YAMATO 								K_AM_DIR, R_AM_DIR_DATA, am_blacklist)
310bee78c38SMasatake YAMATO 		);
311bee78c38SMasatake YAMATO }
312bee78c38SMasatake YAMATO 
inputStart(subparser * s)313c70c75f4SMasatake YAMATO static void inputStart (subparser *s)
314c70c75f4SMasatake YAMATO {
315c70c75f4SMasatake YAMATO 	struct sAutomakeSubparser *automake = (struct sAutomakeSubparser*)s;
316c70c75f4SMasatake YAMATO 
317c70c75f4SMasatake YAMATO 	automake->directories = hashTableNew (11, hashCstrhash, hashCstreq, eFree, eFree);
318c70c75f4SMasatake YAMATO 	automake->index = CORK_NIL;
319b245a051SMasatake YAMATO 	automake->in_subdirs = false;
320c70c75f4SMasatake YAMATO }
321c70c75f4SMasatake YAMATO 
inputEnd(subparser * s)322c70c75f4SMasatake YAMATO static void inputEnd (subparser *s)
323c70c75f4SMasatake YAMATO {
324c70c75f4SMasatake YAMATO 	struct sAutomakeSubparser *automake = (struct sAutomakeSubparser*)s;
325c70c75f4SMasatake YAMATO 
326c70c75f4SMasatake YAMATO 	hashTableDelete (automake->directories);
327c70c75f4SMasatake YAMATO 	automake->directories = NULL;
328c70c75f4SMasatake YAMATO }
329c70c75f4SMasatake YAMATO 
findAutomakeTags(void)330bee78c38SMasatake YAMATO static void findAutomakeTags (void)
331bee78c38SMasatake YAMATO {
332c70c75f4SMasatake YAMATO 	scheduleRunningBaseparser (0);
333bee78c38SMasatake YAMATO }
334bee78c38SMasatake YAMATO 
AutomakeParser(void)335bee78c38SMasatake YAMATO extern parserDefinition* AutomakeParser (void)
336bee78c38SMasatake YAMATO {
33767ab9297SMasatake YAMATO 	static const char *const extensions [] = { "am", NULL };
338*be440f85SMasatake YAMATO 	static const char *const patterns [] = { "Makefile.am", "GNUmakefile.am", NULL };
339c70c75f4SMasatake YAMATO 	static struct sAutomakeSubparser automakeSubparser = {
340c70c75f4SMasatake YAMATO 		.make = {
341c70c75f4SMasatake YAMATO 			.subparser = {
342c70c75f4SMasatake YAMATO 				.direction = SUBPARSER_SUB_RUNS_BASE,
343c70c75f4SMasatake YAMATO 				.inputStart = inputStart,
344c70c75f4SMasatake YAMATO 				.inputEnd = inputEnd,
345c70c75f4SMasatake YAMATO 			},
346c70c75f4SMasatake YAMATO 			.valueNotify = valueCallback,
347c70c75f4SMasatake YAMATO 			.directiveNotify = directiveCallback,
348c70c75f4SMasatake YAMATO 			.newMacroNotify = newMacroCallback,
349c70c75f4SMasatake YAMATO 		},
350c70c75f4SMasatake YAMATO 	};
351c70c75f4SMasatake YAMATO 	static parserDependency dependencies [] = {
352c70c75f4SMasatake YAMATO 		[0] = { DEPTYPE_SUBPARSER, "Make", &automakeSubparser },
353c70c75f4SMasatake YAMATO 	};
354c70c75f4SMasatake YAMATO 
355bee78c38SMasatake YAMATO 	parserDefinition* const def = parserNew ("Automake");
356bee78c38SMasatake YAMATO 
357c70c75f4SMasatake YAMATO 
358c70c75f4SMasatake YAMATO 	def->dependencies = dependencies;
359c70c75f4SMasatake YAMATO 	def->dependencyCount = ARRAY_SIZE(dependencies);
36009ae690fSMasatake YAMATO 	def->kindTable      = AutomakeKinds;
361bee78c38SMasatake YAMATO 	def->kindCount  = ARRAY_SIZE (AutomakeKinds);
36267ab9297SMasatake YAMATO 	def->extensions = extensions;
363bee78c38SMasatake YAMATO 	def->patterns   = patterns;
364bee78c38SMasatake YAMATO 	def->parser     = findAutomakeTags;
3656b1a862eSMasatake YAMATO 	def->useCork    = CORK_QUEUE;
366bee78c38SMasatake YAMATO 	return def;
367bee78c38SMasatake YAMATO }
368