xref: /Universal-ctags/parsers/make.c (revision 34555344617daccf89deb55939c77d6e359e64e6)
13ae02089SMasatake YAMATO /*
23ae02089SMasatake YAMATO *   Copyright (c) 2000-2005, Darren Hiebert
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 makefiles.
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>
163ae02089SMasatake YAMATO #include <ctype.h>
173ae02089SMasatake YAMATO 
1887214e15SMasatake YAMATO #include "make.h"
19bee78c38SMasatake YAMATO 
20a7ea4a72SMasatake YAMATO #include "entry.h"
21918c3462SMasatake YAMATO #include "kind.h"
22*34555344SMasatake YAMATO #include "numarray.h"
233ae02089SMasatake YAMATO #include "parse.h"
243ae02089SMasatake YAMATO #include "read.h"
253db72c21SMasatake YAMATO #include "routines.h"
260d502ef0SMasatake YAMATO #include "strlist.h"
273ae02089SMasatake YAMATO #include "vstring.h"
28918c3462SMasatake YAMATO #include "xtag.h"
293ae02089SMasatake YAMATO 
30bee78c38SMasatake YAMATO 
313ae02089SMasatake YAMATO /*
323ae02089SMasatake YAMATO *   DATA DEFINITIONS
333ae02089SMasatake YAMATO */
343ae02089SMasatake YAMATO typedef enum {
35980eddd6SMasatake YAMATO 	K_MACRO, K_TARGET, K_INCLUDE,
36918c3462SMasatake YAMATO } makeKind;
37918c3462SMasatake YAMATO 
38918c3462SMasatake YAMATO typedef enum {
39918c3462SMasatake YAMATO 	R_INCLUDE_GENERIC,
40918c3462SMasatake YAMATO 	R_INCLUDE_OPTIONAL,
41fc5485bfSMasatake YAMATO } makeMakefileRole;
42918c3462SMasatake YAMATO 
4313457258SMasatake YAMATO static roleDefinition MakeMakefileRoles [] = {
44ce990805SThomas Braun 	{ true, "included", "included" },
45ce990805SThomas Braun 	{ true, "optional", "optionally included"},
46918c3462SMasatake YAMATO };
473ae02089SMasatake YAMATO 
48e112e8abSMasatake YAMATO static kindDefinition MakeKinds [] = {
49ce990805SThomas Braun 	{ true, 'm', "macro",  "macros"},
50ce990805SThomas Braun 	{ true, 't', "target", "targets"},
51ce990805SThomas Braun 	{ true, 'I', "makefile", "makefiles",
52ce990805SThomas Braun 	  .referenceOnly = true, ATTACH_ROLES(MakeMakefileRoles)},
533ae02089SMasatake YAMATO };
543ae02089SMasatake YAMATO 
55574aeb80SMasatake YAMATO 
563ae02089SMasatake YAMATO /*
573ae02089SMasatake YAMATO *   FUNCTION DEFINITIONS
583ae02089SMasatake YAMATO */
593ae02089SMasatake YAMATO 
nextChar(void)603ae02089SMasatake YAMATO static int nextChar (void)
613ae02089SMasatake YAMATO {
62018bce0bSMasatake YAMATO 	int c = getcFromInputFile ();
633ae02089SMasatake YAMATO 	if (c == '\\')
643ae02089SMasatake YAMATO 	{
65018bce0bSMasatake YAMATO 		c = getcFromInputFile ();
663ae02089SMasatake YAMATO 		if (c == '\n')
673ae02089SMasatake YAMATO 			c = nextChar ();
683ae02089SMasatake YAMATO 	}
693ae02089SMasatake YAMATO 	return c;
703ae02089SMasatake YAMATO }
713ae02089SMasatake YAMATO 
skipLine(void)723ae02089SMasatake YAMATO static void skipLine (void)
733ae02089SMasatake YAMATO {
743ae02089SMasatake YAMATO 	int c;
753ae02089SMasatake YAMATO 	do
763ae02089SMasatake YAMATO 		c = nextChar ();
773ae02089SMasatake YAMATO 	while (c != EOF  &&  c != '\n');
783ae02089SMasatake YAMATO 	if (c == '\n')
7961f14fa5SMasatake YAMATO 		ungetcToInputFile (c);
803ae02089SMasatake YAMATO }
813ae02089SMasatake YAMATO 
skipToNonWhite(int c)823ae02089SMasatake YAMATO static int skipToNonWhite (int c)
833ae02089SMasatake YAMATO {
843ae02089SMasatake YAMATO 	while (c != '\n' && isspace (c))
853ae02089SMasatake YAMATO 		c = nextChar ();
863ae02089SMasatake YAMATO 	return c;
873ae02089SMasatake YAMATO }
883ae02089SMasatake YAMATO 
isIdentifier(int c)89ce990805SThomas Braun static bool isIdentifier (int c)
903ae02089SMasatake YAMATO {
91ce990805SThomas Braun 	return (bool)(c != '\0' && (isalnum (c)  ||  strchr (".-_/$(){}%", c) != NULL));
923ae02089SMasatake YAMATO }
933ae02089SMasatake YAMATO 
isSpecialTarget(vString * const name)94ce990805SThomas Braun static bool isSpecialTarget (vString *const name)
953ae02089SMasatake YAMATO {
963ae02089SMasatake YAMATO 	size_t i = 0;
973ae02089SMasatake YAMATO 	/* All special targets begin with '.'. */
983ae02089SMasatake YAMATO 	if (vStringLength (name) < 1 || vStringChar (name, i++) != '.') {
99ce990805SThomas Braun 		return false;
1003ae02089SMasatake YAMATO 	}
1013ae02089SMasatake YAMATO 	while (i < vStringLength (name)) {
1023ae02089SMasatake YAMATO 		char ch = vStringChar (name, i++);
1033ae02089SMasatake YAMATO 		if (ch != '_' && !isupper (ch))
1043ae02089SMasatake YAMATO 		{
105ce990805SThomas Braun 			return false;
1063ae02089SMasatake YAMATO 		}
1073ae02089SMasatake YAMATO 	}
108ce990805SThomas Braun 	return true;
1093ae02089SMasatake YAMATO }
1103ae02089SMasatake YAMATO 
makeSimpleMakeTag(vString * const name,makeKind kind)111a7ea4a72SMasatake YAMATO static int makeSimpleMakeTag (vString *const name, makeKind kind)
112bee78c38SMasatake YAMATO {
113c70c75f4SMasatake YAMATO 	if (!isLanguageEnabled (getInputLanguage ()))
114a7ea4a72SMasatake YAMATO 		return CORK_NIL;
11588202471SMasatake YAMATO 
116a7ea4a72SMasatake YAMATO 	return makeSimpleTag (name, kind);
117bee78c38SMasatake YAMATO }
118bee78c38SMasatake YAMATO 
makeSimpleMakeRefTag(const vString * const name,const int kind,int roleIndex)119f92e6bf2SMasatake YAMATO static void makeSimpleMakeRefTag (const vString* const name, const int kind,
120bee78c38SMasatake YAMATO 				  int roleIndex)
121bee78c38SMasatake YAMATO {
122c70c75f4SMasatake YAMATO 	if (!isLanguageEnabled (getInputLanguage ()))
12388202471SMasatake YAMATO 		return;
12488202471SMasatake YAMATO 
12516a2541cSMasatake YAMATO 	makeSimpleRefTag (name, kind, roleIndex);
126bee78c38SMasatake YAMATO }
127bee78c38SMasatake YAMATO 
newTarget(vString * const name)128*34555344SMasatake YAMATO static int newTarget (vString *const name)
1293ae02089SMasatake YAMATO {
1303ae02089SMasatake YAMATO 	/* Ignore GNU Make's "special targets". */
1313ae02089SMasatake YAMATO 	if  (isSpecialTarget (name))
1323ae02089SMasatake YAMATO 	{
133*34555344SMasatake YAMATO 		return CORK_NIL;
1343ae02089SMasatake YAMATO 	}
135*34555344SMasatake YAMATO 	return makeSimpleMakeTag (name, K_TARGET);
1363ae02089SMasatake YAMATO }
1373ae02089SMasatake YAMATO 
newMacro(vString * const name,bool with_define_directive,bool appending)138a7ea4a72SMasatake YAMATO static int newMacro (vString *const name, bool with_define_directive, bool appending)
1393ae02089SMasatake YAMATO {
140a7ea4a72SMasatake YAMATO 	int r = CORK_NIL;
141c70c75f4SMasatake YAMATO 	subparser *s;
142c70c75f4SMasatake YAMATO 
143574aeb80SMasatake YAMATO 	if (!appending)
144a7ea4a72SMasatake YAMATO 		r = makeSimpleMakeTag (name, K_MACRO);
145c70c75f4SMasatake YAMATO 
14611358a9dSMasatake YAMATO 	foreachSubparser(s, false)
147c70c75f4SMasatake YAMATO 	{
148c70c75f4SMasatake YAMATO 		makeSubparser *m = (makeSubparser *)s;
149c70c75f4SMasatake YAMATO 		enterSubparser(s);
150c70c75f4SMasatake YAMATO 		if (m->newMacroNotify)
151c70c75f4SMasatake YAMATO 			m->newMacroNotify (m, vStringValue(name), with_define_directive, appending);
152c70c75f4SMasatake YAMATO 		leaveSubparser();
153c70c75f4SMasatake YAMATO 	}
154a7ea4a72SMasatake YAMATO 
155a7ea4a72SMasatake YAMATO 	return r;
156c70c75f4SMasatake YAMATO }
157c70c75f4SMasatake YAMATO 
valueFound(vString * const name)158c70c75f4SMasatake YAMATO static void valueFound (vString *const name)
159c70c75f4SMasatake YAMATO {
160c70c75f4SMasatake YAMATO 	subparser *s;
16111358a9dSMasatake YAMATO 	foreachSubparser(s, false)
162c70c75f4SMasatake YAMATO 	{
163c70c75f4SMasatake YAMATO 		makeSubparser *m = (makeSubparser *)s;
164c70c75f4SMasatake YAMATO 		enterSubparser(s);
165c70c75f4SMasatake YAMATO 		if (m->valueNotify)
166c70c75f4SMasatake YAMATO 			m->valueNotify (m, vStringValue (name));
167c70c75f4SMasatake YAMATO 		leaveSubparser();
168c70c75f4SMasatake YAMATO 	}
169c70c75f4SMasatake YAMATO }
170c70c75f4SMasatake YAMATO 
directiveFound(vString * const name)171c70c75f4SMasatake YAMATO static void directiveFound (vString *const name)
172c70c75f4SMasatake YAMATO {
173c70c75f4SMasatake YAMATO 	subparser *s;
17411358a9dSMasatake YAMATO 	foreachSubparser (s, false)
175c70c75f4SMasatake YAMATO 	{
176c70c75f4SMasatake YAMATO 		makeSubparser *m = (makeSubparser *)s;
177c70c75f4SMasatake YAMATO 		enterSubparser(s);
178c70c75f4SMasatake YAMATO 		if (m->directiveNotify)
179c70c75f4SMasatake YAMATO 			m->directiveNotify (m, vStringValue (name));
180c70c75f4SMasatake YAMATO 		leaveSubparser();
181c70c75f4SMasatake YAMATO 	}
1823ae02089SMasatake YAMATO }
1833ae02089SMasatake YAMATO 
newInclude(vString * const name,bool optional)184ce990805SThomas Braun static void newInclude (vString *const name, bool optional)
185144ef5afSMasatake YAMATO {
186f92e6bf2SMasatake YAMATO 	makeSimpleMakeRefTag (name, K_INCLUDE,
187918c3462SMasatake YAMATO 			      optional? R_INCLUDE_OPTIONAL: R_INCLUDE_GENERIC);
188144ef5afSMasatake YAMATO }
189144ef5afSMasatake YAMATO 
isAcceptableAsInclude(vString * const name)190ce990805SThomas Braun static bool isAcceptableAsInclude (vString *const name)
191144ef5afSMasatake YAMATO {
192144ef5afSMasatake YAMATO 	if (strcmp (vStringValue (name), "$") == 0)
193ce990805SThomas Braun 		return false;
194ce990805SThomas Braun 	return true;
195144ef5afSMasatake YAMATO }
196144ef5afSMasatake YAMATO 
readIdentifier(const int first,vString * const id)1973ae02089SMasatake YAMATO static void readIdentifier (const int first, vString *const id)
1983ae02089SMasatake YAMATO {
1993ae02089SMasatake YAMATO 	int depth = 0;
2003ae02089SMasatake YAMATO 	int c = first;
2013ae02089SMasatake YAMATO 	vStringClear (id);
2023ae02089SMasatake YAMATO 	while (isIdentifier (c) || (depth > 0 && c != EOF && c != '\n'))
2033ae02089SMasatake YAMATO 	{
20439c1236cSMasatake YAMATO 		if (c == '(' || c == '{')
2053ae02089SMasatake YAMATO 			depth++;
2063ae02089SMasatake YAMATO 		else if (depth > 0 && (c == ')' || c == '}'))
2073ae02089SMasatake YAMATO 			depth--;
2083ae02089SMasatake YAMATO 		vStringPut (id, c);
2093ae02089SMasatake YAMATO 		c = nextChar ();
2103ae02089SMasatake YAMATO 	}
21161f14fa5SMasatake YAMATO 	ungetcToInputFile (c);
2123ae02089SMasatake YAMATO }
2133ae02089SMasatake YAMATO 
endTargets(intArray * targets,unsigned long lnum)214*34555344SMasatake YAMATO static void endTargets (intArray *targets, unsigned long lnum)
215*34555344SMasatake YAMATO {
216*34555344SMasatake YAMATO 	for (unsigned int i = 0; i < intArrayCount (targets); i++)
217*34555344SMasatake YAMATO 	{
218*34555344SMasatake YAMATO 		int cork_index = intArrayItem (targets, i);
219*34555344SMasatake YAMATO 		tagEntryInfo *e = getEntryInCorkQueue (cork_index);
220*34555344SMasatake YAMATO 		if (e)
221*34555344SMasatake YAMATO 			e->extensionFields.endLine = lnum;
222*34555344SMasatake YAMATO 	}
223*34555344SMasatake YAMATO 	intArrayClear (targets);
224*34555344SMasatake YAMATO }
225*34555344SMasatake YAMATO 
findMakeTags(void)226c70c75f4SMasatake YAMATO static void findMakeTags (void)
2273ae02089SMasatake YAMATO {
2283ae02089SMasatake YAMATO 	stringList *identifiers = stringListNew ();
229ce990805SThomas Braun 	bool newline = true;
230a7ea4a72SMasatake YAMATO 	int  current_macro = CORK_NIL;
231ce990805SThomas Braun 	bool in_value  = false;
232*34555344SMasatake YAMATO 	intArray *current_targets = intArrayNew ();
233ce990805SThomas Braun 	bool variable_possible = true;
234ce990805SThomas Braun 	bool appending = false;
2353ae02089SMasatake YAMATO 	int c;
236c70c75f4SMasatake YAMATO 	subparser *sub;
2373ae02089SMasatake YAMATO 
238c70c75f4SMasatake YAMATO 	sub = getSubparserRunningBaseparser();
239c70c75f4SMasatake YAMATO 	if (sub)
240c70c75f4SMasatake YAMATO 		chooseExclusiveSubparser (sub, NULL);
241bee78c38SMasatake YAMATO 
2423ae02089SMasatake YAMATO 	while ((c = nextChar ()) != EOF)
2433ae02089SMasatake YAMATO 	{
2443ae02089SMasatake YAMATO 		if (newline)
2453ae02089SMasatake YAMATO 		{
246*34555344SMasatake YAMATO 			if (!intArrayIsEmpty (current_targets))
2473ae02089SMasatake YAMATO 			{
2483ae02089SMasatake YAMATO 				if (c == '\t' || (c = skipToNonWhite (c)) == '#')
2493ae02089SMasatake YAMATO 				{
2503ae02089SMasatake YAMATO 					skipLine ();  /* skip rule or comment */
2513ae02089SMasatake YAMATO 					c = nextChar ();
2523ae02089SMasatake YAMATO 				}
2533ae02089SMasatake YAMATO 				else if (c != '\n')
254*34555344SMasatake YAMATO 					endTargets (current_targets, getInputLineNumber () - 1);
2553ae02089SMasatake YAMATO 			}
256980eddd6SMasatake YAMATO 			else if (in_value)
257ce990805SThomas Braun 				in_value = false;
258980eddd6SMasatake YAMATO 
2593ae02089SMasatake YAMATO 			stringListClear (identifiers);
260*34555344SMasatake YAMATO 			variable_possible = intArrayIsEmpty (current_targets);
261ce990805SThomas Braun 			newline = false;
2623ae02089SMasatake YAMATO 		}
2633ae02089SMasatake YAMATO 		if (c == '\n')
264ce990805SThomas Braun 			newline = true;
2653ae02089SMasatake YAMATO 		else if (isspace (c))
2663ae02089SMasatake YAMATO 			continue;
2673ae02089SMasatake YAMATO 		else if (c == '#')
2683ae02089SMasatake YAMATO 			skipLine ();
2693ae02089SMasatake YAMATO 		else if (variable_possible && c == '?')
2703ae02089SMasatake YAMATO 		{
2713ae02089SMasatake YAMATO 			c = nextChar ();
27261f14fa5SMasatake YAMATO 			ungetcToInputFile (c);
2733ae02089SMasatake YAMATO 			variable_possible = (c == '=');
2743ae02089SMasatake YAMATO 		}
275574aeb80SMasatake YAMATO 		else if (variable_possible && c == '+')
276574aeb80SMasatake YAMATO 		{
277574aeb80SMasatake YAMATO 			c = nextChar ();
278574aeb80SMasatake YAMATO 			ungetcToInputFile (c);
279574aeb80SMasatake YAMATO 			variable_possible = (c == '=');
280ce990805SThomas Braun 			appending = true;
281574aeb80SMasatake YAMATO 		}
282c7cfa48dSMasatake YAMATO 		else if ((! in_value) && variable_possible && c == ':' &&
2833ae02089SMasatake YAMATO 				 stringListCount (identifiers) > 0)
2843ae02089SMasatake YAMATO 		{
2853ae02089SMasatake YAMATO 			c = nextChar ();
28661f14fa5SMasatake YAMATO 			ungetcToInputFile (c);
2873ae02089SMasatake YAMATO 			if (c != '=')
2883ae02089SMasatake YAMATO 			{
2893ae02089SMasatake YAMATO 				unsigned int i;
2903ae02089SMasatake YAMATO 				for (i = 0; i < stringListCount (identifiers); i++)
291*34555344SMasatake YAMATO 				{
292*34555344SMasatake YAMATO 					int r = newTarget (stringListItem (identifiers, i));
293*34555344SMasatake YAMATO 					if (r != CORK_NIL)
294*34555344SMasatake YAMATO 						intArrayAdd (current_targets, r);
295*34555344SMasatake YAMATO 				}
2963ae02089SMasatake YAMATO 				stringListClear (identifiers);
2973ae02089SMasatake YAMATO 			}
2983ae02089SMasatake YAMATO 		}
2993ae02089SMasatake YAMATO 		else if (variable_possible && c == '=' &&
3003ae02089SMasatake YAMATO 				 stringListCount (identifiers) == 1)
3013ae02089SMasatake YAMATO 		{
302c70c75f4SMasatake YAMATO 			newMacro (stringListItem (identifiers, 0), false, appending);
303c70c75f4SMasatake YAMATO 
304ce990805SThomas Braun 			in_value = true;
305*34555344SMasatake YAMATO 			endTargets (current_targets, getInputLineNumber () - 1);
306ce990805SThomas Braun 			appending = false;
3073ae02089SMasatake YAMATO 		}
3083ae02089SMasatake YAMATO 		else if (variable_possible && isIdentifier (c))
3093ae02089SMasatake YAMATO 		{
3103ae02089SMasatake YAMATO 			vString *name = vStringNew ();
3113ae02089SMasatake YAMATO 			readIdentifier (c, name);
3123ae02089SMasatake YAMATO 			stringListAdd (identifiers, name);
3133ae02089SMasatake YAMATO 
314c70c75f4SMasatake YAMATO 			if (in_value)
315c70c75f4SMasatake YAMATO 				valueFound(name);
316980eddd6SMasatake YAMATO 
3173ae02089SMasatake YAMATO 			if (stringListCount (identifiers) == 1)
3183ae02089SMasatake YAMATO 			{
319a7ea4a72SMasatake YAMATO 				if ((current_macro != CORK_NIL) && ! strcmp (vStringValue (name), "endef"))
320a7ea4a72SMasatake YAMATO 				{
321a7ea4a72SMasatake YAMATO 					tagEntryInfo *e = getEntryInCorkQueue(current_macro);
322a7ea4a72SMasatake YAMATO 
323a7ea4a72SMasatake YAMATO 					current_macro = CORK_NIL;
324a7ea4a72SMasatake YAMATO 					if (e)
325a7ea4a72SMasatake YAMATO 						e->extensionFields.endLine = getInputLineNumber ();
326a7ea4a72SMasatake YAMATO 				}
327a7ea4a72SMasatake YAMATO 				else if (current_macro != CORK_NIL)
3283ae02089SMasatake YAMATO 					skipLine ();
3293ae02089SMasatake YAMATO 				else if (! strcmp (vStringValue (name), "define"))
3303ae02089SMasatake YAMATO 				{
3313ae02089SMasatake YAMATO 					c = skipToNonWhite (nextChar ());
3323ae02089SMasatake YAMATO 					vStringClear (name);
3333ae02089SMasatake YAMATO 					/* all remaining characters on the line are the name -- even spaces */
3343ae02089SMasatake YAMATO 					while (c != EOF && c != '\n')
3353ae02089SMasatake YAMATO 					{
3363ae02089SMasatake YAMATO 						vStringPut (name, c);
3373ae02089SMasatake YAMATO 						c = nextChar ();
3383ae02089SMasatake YAMATO 					}
3393ae02089SMasatake YAMATO 					if (c == '\n')
34061f14fa5SMasatake YAMATO 						ungetcToInputFile (c);
3413ae02089SMasatake YAMATO 					vStringStripTrailing (name);
342c70c75f4SMasatake YAMATO 
343a7ea4a72SMasatake YAMATO 					current_macro = newMacro (name, true, false);
3443ae02089SMasatake YAMATO 				}
3453ae02089SMasatake YAMATO 				else if (! strcmp (vStringValue (name), "export"))
3463ae02089SMasatake YAMATO 					stringListClear (identifiers);
347144ef5afSMasatake YAMATO 				else if (! strcmp (vStringValue (name), "include")
348144ef5afSMasatake YAMATO 					 || ! strcmp (vStringValue (name), "sinclude")
349144ef5afSMasatake YAMATO 					 || ! strcmp (vStringValue (name), "-include"))
350144ef5afSMasatake YAMATO 				{
351ce990805SThomas Braun 					bool optional = (vStringValue (name)[0] == 'i')? false: true;
352144ef5afSMasatake YAMATO 					while (1)
353144ef5afSMasatake YAMATO 					{
354144ef5afSMasatake YAMATO 						c = skipToNonWhite (nextChar ());
355144ef5afSMasatake YAMATO 						readIdentifier (c, name);
356144ef5afSMasatake YAMATO 						vStringStripTrailing (name);
357144ef5afSMasatake YAMATO 						if (isAcceptableAsInclude(name))
358918c3462SMasatake YAMATO 							newInclude (name, optional);
359144ef5afSMasatake YAMATO 
360144ef5afSMasatake YAMATO 						/* non-space characters after readIdentifier() may
361144ef5afSMasatake YAMATO 						 * be rejected by the function:
362144ef5afSMasatake YAMATO 						 * e.g.
363144ef5afSMasatake YAMATO 						 * include $*
364144ef5afSMasatake YAMATO 						 *
365144ef5afSMasatake YAMATO 						 * Here, remove such characters from input stream.
366144ef5afSMasatake YAMATO 						 */
367144ef5afSMasatake YAMATO 						do
368144ef5afSMasatake YAMATO 							c = nextChar ();
369144ef5afSMasatake YAMATO 						while (c != EOF && c != '\n' && (!isspace (c)));
370144ef5afSMasatake YAMATO 						if (c == '\n')
37161f14fa5SMasatake YAMATO 							ungetcToInputFile (c);
372144ef5afSMasatake YAMATO 
373144ef5afSMasatake YAMATO 						if (c == EOF || c == '\n')
374144ef5afSMasatake YAMATO 							break;
375144ef5afSMasatake YAMATO 					}
376144ef5afSMasatake YAMATO 				}
3772121904eSMasatake YAMATO 				else
378c70c75f4SMasatake YAMATO 					directiveFound (name);
3793ae02089SMasatake YAMATO 			}
3803ae02089SMasatake YAMATO 		}
3813ae02089SMasatake YAMATO 		else
382ce990805SThomas Braun 			variable_possible = false;
3833ae02089SMasatake YAMATO 	}
3843ae02089SMasatake YAMATO 
385*34555344SMasatake YAMATO 	endTargets (current_targets, getInputLineNumber ());
386*34555344SMasatake YAMATO 
387*34555344SMasatake YAMATO 	intArrayDelete (current_targets);
388c70c75f4SMasatake YAMATO 	stringListDelete (identifiers);
389980eddd6SMasatake YAMATO }
390980eddd6SMasatake YAMATO 
391980eddd6SMasatake YAMATO 
MakefileParser(void)3923ae02089SMasatake YAMATO extern parserDefinition* MakefileParser (void)
3933ae02089SMasatake YAMATO {
3943ae02089SMasatake YAMATO 	static const char *const patterns [] = { "[Mm]akefile", "GNUmakefile", NULL };
3953ae02089SMasatake YAMATO 	static const char *const extensions [] = { "mak", "mk", NULL };
396b7d13f13SMasatake YAMATO 	static const char *const aliases [] = {
397b7d13f13SMasatake YAMATO 		/* the mode name in emacs */
398b7d13f13SMasatake YAMATO 		"makefile",
399b7d13f13SMasatake YAMATO 		NULL };
4003ae02089SMasatake YAMATO 	parserDefinition* const def = parserNew ("Make");
40109ae690fSMasatake YAMATO 	def->kindTable      = MakeKinds;
4023db72c21SMasatake YAMATO 	def->kindCount  = ARRAY_SIZE (MakeKinds);
4033ae02089SMasatake YAMATO 	def->patterns   = patterns;
4043ae02089SMasatake YAMATO 	def->extensions = extensions;
405b7d13f13SMasatake YAMATO 	def->aliases = aliases;
4063ae02089SMasatake YAMATO 	def->parser     = findMakeTags;
407a7ea4a72SMasatake YAMATO 	def->useCork = CORK_QUEUE;
4083ae02089SMasatake YAMATO 	return def;
4093ae02089SMasatake YAMATO }
410