Improve Makefile parser for better parsing of targets (from CTags' patches tracker, for reference this is patch v3).

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@2497 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2008-04-17 18:06:31 +00:00
parent d9690cbe77
commit 3daa3011e4
2 changed files with 88 additions and 21 deletions

View File

@ -7,6 +7,9 @@
tagmanager filename (patch by Yura Siamashka, thanks).
This makes it also possible to add navigation history items for files
without a tagmanager filename.
* tagmanager/make.c:
Improve Makefile parser for better parsing of targets
(from CTags' patches tracker, for reference this is patch v3).
2008-04-16 Frank Lanitz <frank(at)frank(dot)uvena(dot)de>

View File

@ -31,8 +31,8 @@ typedef enum {
} shKind;
static kindOption MakeKinds [] = {
{ TRUE, 'm', "macro", "macros"},
{ TRUE, 'f', "function", "targets"}
{ TRUE, 'm', "macro", "macros"},
{ TRUE, 't', "function", "targets"}
};
/*
@ -72,17 +72,68 @@ static int skipToNonWhite (void)
static boolean isIdentifier (int c)
{
return (boolean)(c != '\0' && (isalnum (c) || strchr (".-_", c) != NULL));
return (boolean)(c != '\0' && (isalnum (c) || strchr (".-_/", c) != NULL));
}
static boolean isSpecialTarget (vString *const name)
{
size_t i = 0;
/* All special targets begin with '.'. */
if (vStringChar (name, i++) != '.') {
return FALSE;
}
while (i < vStringLength (name)) {
char ch = vStringChar (name, i++);
if (ch != '_' && !isupper (ch))
{
return FALSE;
}
}
return TRUE;
}
static void newTarget (vString *const name)
{
/* Ignore GNU Make's "special targets". */
if (isSpecialTarget (name))
{
return;
}
makeSimpleTag (name, MakeKinds, K_TARGET);
}
static void newMacro (vString *const name)
{
makeSimpleTag (name, MakeKinds, K_MACRO);
}
static void newMacroFromDefine (vString *const name)
{
/* name is something like "define JAVAHPP_RULE", find the space and jump to the next char */
vStringCopyS (name, strchr (vStringValue (name), ' ') + 1);
makeSimpleTag (name, MakeKinds, K_MACRO);
}
static void readIdentifier (const int first, vString *const id)
{
int c = first;
int c_prev = first;
int c_next = first;
vStringClear (id);
while (isIdentifier (c))
while (isIdentifier (c) || c == ' ')
{
vStringPut (id, c);
c = nextChar ();
c_next = nextChar ();
if (c == ' ') {
/* add the space character only if the previous and
* next character are valid identifiers */
if (isIdentifier (c_prev) && isIdentifier (c_next))
vStringPut (id, c);
}
else {
vStringPut (id, c);
}
c_prev = c;
c = c_next;
}
fileUngetc (c);
vStringTerminate (id);
@ -133,7 +184,6 @@ static void findMakeTags (void)
else
in_rule = FALSE;
}
variable_possible = (boolean)(!in_rule);
newline = FALSE;
}
@ -155,18 +205,16 @@ static void findMakeTags (void)
else if (variable_possible && isIdentifier (c))
{
readIdentifier (c, name);
if (strcmp (vStringValue (name), "endef") == 0)
if (strncmp (vStringValue (name), "endef", 5) == 0)
in_define = FALSE;
else if (in_define)
skipLine ();
else if (strcmp (vStringValue (name), "define") == 0 &&
else if (strncmp (vStringValue (name), "define", 6) == 0 &&
isIdentifier (c))
{
in_define = TRUE;
c = skipToNonWhite ();
readIdentifier (c, name);
makeSimpleTag (name, MakeKinds, K_MACRO);
newMacroFromDefine (name);
skipLine ();
}
else {
@ -174,26 +222,42 @@ static void findMakeTags (void)
if (strchr (":?+", c) != NULL)
{
boolean append = (boolean)(c == '+');
if (c == ':')
{
in_rule = TRUE;
makeSimpleTag (name, MakeKinds, K_TARGET);
}
boolean was_colon = (c == ':');
c = nextChar ();
if (c != '=')
fileUngetc (c);
if (was_colon)
{
if (c == '=')
{
newMacro (name);
in_rule = FALSE;
skipLine ();
}
else
{
in_rule = TRUE;
newTarget (name);
}
}
else if (append)
{
skipLine ();
continue;
}
else
{
fileUngetc (c);
}
}
if (c == '=')
else if (c == '=')
{
makeSimpleTag (name, MakeKinds, K_MACRO);
newMacro (name);
in_rule = FALSE;
skipLine ();
}
else
{
fileUngetc (c);
}
}
}
else