From 3daa3011e4223dc578b543f2d8f67c9ef248ec62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Tr=C3=B6ger?= Date: Thu, 17 Apr 2008 18:06:31 +0000 Subject: [PATCH] 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 --- ChangeLog | 3 ++ tagmanager/make.c | 106 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 88 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index b930f683..298d3d19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/tagmanager/make.c b/tagmanager/make.c index 64ba9698..39a91ebc 100644 --- a/tagmanager/make.c +++ b/tagmanager/make.c @@ -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