SF.net SVN: geany: [2388] trunk

eht16 at users.sourceforge.net eht16 at xxxxx
Sun Mar 23 15:25:43 UTC 2008


Revision: 2388
          http://geany.svn.sourceforge.net/geany/?rev=2388&view=rev
Author:   eht16
Date:     2008-03-23 08:25:42 -0700 (Sun, 23 Mar 2008)

Log Message:
-----------
Update Makefile parser from CTags SVN and improve it to detect targets in Makefiles.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/symbols.c
    trunk/tagmanager/make.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-03-23 14:57:53 UTC (rev 2387)
+++ trunk/ChangeLog	2008-03-23 15:25:42 UTC (rev 2388)
@@ -4,6 +4,9 @@
    src/highlighting.c:
    Add styles to customize line and search marker and add
    translucency setting.
+ * tagmanager/make.c, src/symbols.c:
+   Update Makefile parser from CTags SVN and improve it to detect
+   targets in Makefiles.
 
 
 2008-03-21  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>

Modified: trunk/src/symbols.c
===================================================================
--- trunk/src/symbols.c	2008-03-23 14:57:53 UTC (rev 2387)
+++ trunk/src/symbols.c	2008-03-23 15:25:42 UTC (rev 2388)
@@ -740,6 +740,12 @@
 				NULL);
 			break;
 		}
+		case GEANY_FILETYPES_MAKE:
+			tag_list_add_groups(tag_store,
+				&tv_iters.tag_function, _("Targets"), "classviewer-method",
+				&tv_iters.tag_macro, _("Macros"), "classviewer-macro",
+				NULL);
+			break;
 		case GEANY_FILETYPES_D:
 		default:
 		{

Modified: trunk/tagmanager/make.c
===================================================================
--- trunk/tagmanager/make.c	2008-03-23 14:57:53 UTC (rev 2387)
+++ trunk/tagmanager/make.c	2008-03-23 15:25:42 UTC (rev 2388)
@@ -1,6 +1,7 @@
 /*
+*   $Id$
 *
-*   Copyright (c) 2000-2001, Darren Hiebert
+*   Copyright (c) 2000-2005, Darren Hiebert
 *
 *   This source code is released for free distribution under the terms of the
 *   GNU General Public License.
@@ -11,10 +12,13 @@
 /*
 *   INCLUDE FILES
 */
-#include "general.h"	/* must always come first */
+#include "general.h"  /* must always come first */
 
+#include <stdio.h>
+#include <string.h>
 #include <ctype.h>
 
+#include "options.h"
 #include "parse.h"
 #include "read.h"
 #include "vstring.h"
@@ -23,80 +27,192 @@
 *   DATA DEFINITIONS
 */
 typedef enum {
-    K_MACRO
+	K_MACRO, K_TARGET
 } shKind;
 
 static kindOption MakeKinds [] = {
-    { TRUE, 'm', "macro", "macros"}
+	{ TRUE, 'm', "macro", "macros"},
+	{ TRUE, 'f', "function", "targets"}
 };
 
 /*
 *   FUNCTION DEFINITIONS
 */
 
+static int nextChar (void)
+{
+	int c = fileGetc ();
+	if (c == '\\')
+	{
+		c = fileGetc ();
+		if (c == '\n')
+			c = fileGetc ();
+	}
+	return c;
+}
+
+static void skipLine (void)
+{
+	int c;
+	do
+		c = nextChar ();
+	while (c != EOF  &&  c != '\n');
+	if (c == '\n')
+		fileUngetc (c);
+}
+
+static int skipToNonWhite (void)
+{
+	int c;
+	do
+		c = nextChar ();
+	while (c != '\n' && isspace (c));
+	return c;
+}
+
 static boolean isIdentifier (int c)
 {
-    return (boolean)(isalnum (c)  ||  c == '_');
+	return (boolean)(c != '\0' && (isalnum (c)  ||  strchr (".-_", c) != NULL));
 }
 
-static void findMakeTags (void)
+static void readIdentifier (const int first, vString *const id)
 {
-    vString *name = vStringNew ();
-    const unsigned char *line;
+	int c = first;
+	vStringClear (id);
+	while (isIdentifier (c))
+	{
+		vStringPut (id, c);
+		c = nextChar ();
+	}
+	fileUngetc (c);
+	vStringTerminate (id);
+}
 
-    while ((line = fileReadLine ()) != NULL)
-    {
-	const unsigned char* cp = line;
-	boolean possible = TRUE;
+static void skipToMatch (const char *const pair)
+{
+	const int begin = pair [0], end = pair [1];
+	const unsigned long inputLineNumber = getInputLineNumber ();
+	int matchLevel = 1;
+	int c = '\0';
 
-	while (isspace ((int) *cp))
-	    ++cp;
-	if (*cp == '#')
-	    continue;
+	while (matchLevel > 0)
+	{
+		c = nextChar ();
+		if (c == begin)
+			++matchLevel;
+		else if (c == end)
+			--matchLevel;
+		else if (c == '\n')
+			break;
+	}
+	if (c == EOF)
+		verbose ("%s: failed to find match for '%c' at line %lu\n",
+				getInputFileName (), begin, inputLineNumber);
+}
 
-	while (*cp != '\0')
+static void findMakeTags (void)
+{
+	vString *name = vStringNew ();
+	boolean newline = TRUE;
+	boolean in_define = FALSE;
+	boolean in_rule = FALSE;
+	boolean variable_possible = TRUE;
+	int c;
+
+	while ((c = nextChar ()) != EOF)
 	{
-	    /*  We look for any sequence of identifier characters following
-	     *  either a white space or a colon and followed by either = or :=
-	     */
-	    if (possible && isIdentifier ((int) *cp))
-	    {
-		while (isIdentifier ((int) *cp))
+		if (newline)
 		{
-		    vStringPut (name, (int) *cp);
-		    ++cp;
+			if (in_rule)
+			{
+				if (c == '\t')
+				{
+					skipLine ();  /* skip rule */
+					continue;
+				}
+				else
+					in_rule = FALSE;
+			}
+
+			variable_possible = (boolean)(!in_rule);
+			newline = FALSE;
 		}
-		vStringTerminate (name);
-		while (isspace ((int) *cp))
-		    ++cp;
-		if ( *cp == ':')
-		    ++cp;
-		if ( *cp == '=')
-		    makeSimpleTag (name, MakeKinds, K_MACRO);
-		vStringClear (name);
-	    }
-	    else if (isspace ((int) *cp) ||  *cp == ':')
-		possible = TRUE;
-	    else
-		possible = FALSE;
-	    if (*cp != '\0')
-		++cp;
+		if (c == '\n')
+			newline = TRUE;
+		else if (isspace (c))
+			continue;
+		else if (c == '#')
+			skipLine ();
+		else if (c == '(')
+			skipToMatch ("()");
+		else if (c == '{')
+			skipToMatch ("{}");
+		else if (c == ':')
+		{
+			variable_possible = TRUE;
+			in_rule = TRUE;
+		}
+		else if (variable_possible && isIdentifier (c))
+		{
+			readIdentifier (c, name);
+
+			if (strcmp (vStringValue (name), "endef") == 0)
+				in_define = FALSE;
+			else if (in_define)
+				skipLine ();
+			else if (strcmp (vStringValue (name), "define") == 0  &&
+				isIdentifier (c))
+			{
+				in_define = TRUE;
+				c = skipToNonWhite ();
+				readIdentifier (c, name);
+				makeSimpleTag (name, MakeKinds, K_MACRO);
+				skipLine ();
+			}
+			else {
+				c = skipToNonWhite ();
+				if (strchr (":?+", c) != NULL)
+				{
+					boolean append = (boolean)(c == '+');
+					if (c == ':')
+					{
+						in_rule = TRUE;
+						makeSimpleTag (name, MakeKinds, K_TARGET);
+					}
+					c = nextChar ();
+					if (c != '=')
+						fileUngetc (c);
+					else if (append)
+					{
+						skipLine ();
+						continue;
+					}
+				}
+				if (c == '=')
+				{
+					makeSimpleTag (name, MakeKinds, K_MACRO);
+					in_rule = FALSE;
+					skipLine ();
+				}
+			}
+		}
+		else
+			variable_possible = FALSE;
 	}
-    }
-    vStringDelete (name);
+	vStringDelete (name);
 }
 
 extern parserDefinition* MakefileParser (void)
 {
-    static const char *const patterns [] = { "[Mm]akefile", NULL };
-    static const char *const extensions [] = { "mak", "mk", NULL };
-    parserDefinition* const def = parserNew ("Make");
-    def->kinds      = MakeKinds;
-    def->kindCount  = KIND_COUNT (MakeKinds);
-    def->patterns   = patterns;
-    def->extensions = extensions;
-    def->parser     = findMakeTags;
-    return def;
+	static const char *const patterns [] = { "[Mm]akefile", NULL };
+	static const char *const extensions [] = { "mak", "mk", NULL };
+	parserDefinition* const def = parserNew ("Make");
+	def->kinds      = MakeKinds;
+	def->kindCount  = KIND_COUNT (MakeKinds);
+	def->patterns   = patterns;
+	def->extensions = extensions;
+	def->parser     = findMakeTags;
+	return def;
 }
 
-/* vi:set tabstop=8 shiftwidth=4: */
+/* vi:set tabstop=4 shiftwidth=4: */


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list