2 * Copyright (c) 2000-2005, Darren Hiebert
4 * This source code is released for free distribution under the terms of the
5 * GNU General Public License.
7 * This module contains functions for generating tags for makefiles.
13 #include "general.h" /* must always come first */
31 static kindOption MakeKinds
[] = {
32 { TRUE
, 'm', "macro", "macros"},
33 { TRUE
, 't', "function", "targets"}
37 * FUNCTION DEFINITIONS
40 static int nextChar (void)
52 static void skipLine (void)
57 while (c
!= EOF
&& c
!= '\n');
62 static int skipToNonWhite (void)
67 while (c
!= '\n' && isspace (c
));
71 static boolean
isIdentifier (int c
)
73 return (boolean
)(c
!= '\0' && (isalnum (c
) || strchr (".-_/", c
) != NULL
));
76 static boolean
isSpecialTarget (vString
*const name
)
79 /* All special targets begin with '.'. */
80 if (vStringChar (name
, i
++) != '.') {
83 while (i
< vStringLength (name
)) {
84 char ch
= vStringChar (name
, i
++);
85 if (ch
!= '_' && !isupper (ch
))
93 static void newTarget (vString
*const name
)
95 /* Ignore GNU Make's "special targets". */
96 if (isSpecialTarget (name
))
100 makeSimpleTag (name
, MakeKinds
, K_TARGET
);
103 static void newMacro (vString
*const name
)
105 makeSimpleTag (name
, MakeKinds
, K_MACRO
);
108 static void newMacroFromDefine (vString
*const name
)
110 /* name is something like "define JAVAHPP_RULE", find the space and jump to the next char */
111 char *name_val
= strchr (vStringValue (name
), ' ');
113 if (name_val
!= NULL
) {
114 vStringCopyS (name
, name_val
+ 1);
115 makeSimpleTag (name
, MakeKinds
, K_MACRO
);
119 static void readIdentifier (const int first
, vString
*const id
)
125 while (isIdentifier (c
) || c
== ' ')
127 c_next
= nextChar ();
129 /* add the space character only if the previous and
130 * next character are valid identifiers */
131 if (isIdentifier (c_prev
) && isIdentifier (c_next
))
141 vStringTerminate (id
);
144 static void skipToMatch (const char *const pair
)
146 const int begin
= pair
[0], end
= pair
[1];
147 const unsigned long inputLineNumber
= getInputLineNumber ();
151 while (matchLevel
> 0)
158 else if (c
== '\n' || c
== EOF
)
162 verbose ("%s: failed to find match for '%c' at line %lu\n",
163 getInputFileName (), begin
, inputLineNumber
);
166 static void findMakeTags (void)
168 vString
*name
= vStringNew ();
169 boolean newline
= TRUE
;
170 boolean in_define
= FALSE
;
171 boolean in_rule
= FALSE
;
172 boolean variable_possible
= TRUE
;
175 while ((c
= nextChar ()) != EOF
)
183 skipLine (); /* skip rule */
189 variable_possible
= (boolean
)(!in_rule
);
194 else if (isspace (c
))
204 variable_possible
= TRUE
;
207 else if (variable_possible
&& isIdentifier (c
))
209 readIdentifier (c
, name
);
210 if (strncmp (vStringValue (name
), "endef", 5) == 0)
214 else if (strncmp (vStringValue (name
), "define", 6) == 0 &&
218 c
= skipToNonWhite ();
219 newMacroFromDefine (name
);
223 c
= skipToNonWhite ();
224 if (strchr (":?+", c
) != NULL
)
226 boolean append
= (boolean
)(c
== '+');
227 boolean was_colon
= (c
== ':');
266 variable_possible
= FALSE
;
268 vStringDelete (name
);
271 extern parserDefinition
* MakefileParser (void)
273 static const char *const patterns
[] = { "[Mm]akefile", "GNUmakefile", NULL
};
274 static const char *const extensions
[] = { "mak", "mk", NULL
};
275 parserDefinition
* const def
= parserNew ("Make");
276 def
->kinds
= MakeKinds
;
277 def
->kindCount
= KIND_COUNT (MakeKinds
);
278 def
->patterns
= patterns
;
279 def
->extensions
= extensions
;
280 def
->parser
= findMakeTags
;
284 /* vi:set tabstop=4 shiftwidth=4: */