SF.net SVN: geany: [1558] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Wed May 23 12:32:07 UTC 2007


Revision: 1558
          http://svn.sourceforge.net/geany/?rev=1558&view=rev
Author:   ntrel
Date:     2007-05-23 05:32:06 -0700 (Wed, 23 May 2007)

Log Message:
-----------
Add Haskell tags support from CTags patch on sf.net written by Peter
Strand (thanks).

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/filetypes.c
    trunk/src/symbols.c
    trunk/tagmanager/Makefile.am
    trunk/tagmanager/makefile.win32
    trunk/tagmanager/parsers.h

Added Paths:
-----------
    trunk/tagmanager/haskell.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-05-22 15:31:40 UTC (rev 1557)
+++ trunk/ChangeLog	2007-05-23 12:32:06 UTC (rev 1558)
@@ -1,3 +1,12 @@
+2007-05-23  Nick Treleaven  <nick.treleaven at btinternet.com>
+
+ * src/filetypes.c, src/symbols.c, tagmanager/parsers.h,
+   tagmanager/makefile.win32, tagmanager/haskell.c,
+   tagmanager/Makefile.am:
+   Add Haskell tags support from CTags patch on sf.net written by Peter
+   Strand (thanks).
+
+
 2007-05-22  Nick Treleaven  <nick.treleaven at btinternet.com>
 
  * tagmanager/read.c, tagmanager/read.h, tagmanager/get.h:

Modified: trunk/src/filetypes.c
===================================================================
--- trunk/src/filetypes.c	2007-05-22 15:31:40 UTC (rev 1557)
+++ trunk/src/filetypes.c	2007-05-23 12:32:06 UTC (rev 1558)
@@ -348,9 +348,9 @@
 #define HASKELL
 	filetypes[GEANY_FILETYPES_HASKELL]->id = GEANY_FILETYPES_HASKELL;
 	filetypes[GEANY_FILETYPES_HASKELL]->uid = FILETYPE_UID_HASKELL;
-	filetypes[GEANY_FILETYPES_HASKELL]->lang = -2;
+	filetypes[GEANY_FILETYPES_HASKELL]->lang = 24;
 	filetypes[GEANY_FILETYPES_HASKELL]->name = g_strdup("Haskell");
-	filetypes[GEANY_FILETYPES_HASKELL]->has_tags = FALSE;
+	filetypes[GEANY_FILETYPES_HASKELL]->has_tags = TRUE;
 	filetypes[GEANY_FILETYPES_HASKELL]->title = g_strdup(_("Haskell source file"));
 	filetypes[GEANY_FILETYPES_HASKELL]->extension = g_strdup("hs");
 	filetypes[GEANY_FILETYPES_HASKELL]->pattern = utils_strv_new("*.hs", "*.lhs", NULL);

Modified: trunk/src/symbols.c
===================================================================
--- trunk/src/symbols.c	2007-05-22 15:31:40 UTC (rev 1557)
+++ trunk/src/symbols.c	2007-05-23 12:32:06 UTC (rev 1558)
@@ -413,6 +413,28 @@
 }
 
 
+/* Adds symbol list groups in (iter*, title) pairs.
+ * The list must be ended with NULL. */
+static void G_GNUC_NULL_TERMINATED
+tag_list_add_groups(gint idx, ...)
+{
+	va_list args;
+	GtkTreeIter *iter;
+
+    va_start(args, idx);
+    for (; iter = va_arg(args, GtkTreeIter*), iter != NULL;)
+    {
+		gchar *title = va_arg(args, gchar*);
+
+    	if (title == NULL)
+			break;
+		gtk_tree_store_append(doc_list[idx].tag_store, iter, NULL);
+		gtk_tree_store_set(doc_list[idx].tag_store, iter, 0, title, -1);
+	}
+	va_end(args);
+}
+
+
 static void init_tag_list(gint idx)
 {
 	filetype_id ft_id = doc_list[idx].file_type->id;
@@ -447,6 +469,14 @@
 			//gtk_tree_store_set(doc_list[idx].tag_store, &(tv_iters.tag_namespace), 0, _("Other"), -1);
 			break;
 		}
+		case GEANY_FILETYPES_HASKELL:
+			tag_list_add_groups(idx,
+				&tv_iters.tag_namespace, _("Module"),
+				&tv_iters.tag_struct, _("Types"),
+				&tv_iters.tag_macro, _("Type constructors"),
+				&tv_iters.tag_function, _("Functions"),
+				NULL);
+			break;
 		case GEANY_FILETYPES_LATEX:
 		{
 			gtk_tree_store_append(doc_list[idx].tag_store, &(tv_iters.tag_function), NULL);
@@ -472,7 +502,7 @@
 			gtk_tree_store_append(doc_list[idx].tag_store, &(tv_iters.tag_class), NULL);
 			gtk_tree_store_set(doc_list[idx].tag_store, &(tv_iters.tag_class), 0, _("Package"), -1);
 			gtk_tree_store_append(doc_list[idx].tag_store, &(tv_iters.tag_function), NULL);
-			gtk_tree_store_set(doc_list[idx].tag_store, &(tv_iters.tag_function), 0, _("Function"), -1);
+			gtk_tree_store_set(doc_list[idx].tag_store, &(tv_iters.tag_function), 0, _("Functions"), -1);
 			gtk_tree_store_append(doc_list[idx].tag_store, &(tv_iters.tag_member), NULL);
 			gtk_tree_store_set(doc_list[idx].tag_store, &(tv_iters.tag_member), 0, _("My"), -1);
 			gtk_tree_store_append(doc_list[idx].tag_store, &(tv_iters.tag_macro), NULL);
@@ -617,6 +647,8 @@
 	GtkTreeIter iter;
 	GtkTreeModel *model;
 
+	g_return_val_if_fail(DOC_IDX_VALID(idx), FALSE);
+
 	tags = get_tag_list(idx, tm_tag_max_t);
 	if (doc_list[idx].tm_file == NULL || tags == NULL) return FALSE;
 

Modified: trunk/tagmanager/Makefile.am
===================================================================
--- trunk/tagmanager/Makefile.am	2007-05-22 15:31:40 UTC (rev 1557)
+++ trunk/tagmanager/Makefile.am	2007-05-23 12:32:06 UTC (rev 1558)
@@ -32,6 +32,7 @@
 	diff.c\
 	docbook.c\
 	fortran.c\
+	haskell.c\
 	js.c\
 	lua.c\
 	make.c\

Added: trunk/tagmanager/haskell.c
===================================================================
--- trunk/tagmanager/haskell.c	                        (rev 0)
+++ trunk/tagmanager/haskell.c	2007-05-23 12:32:06 UTC (rev 1558)
@@ -0,0 +1,358 @@
+
+/*
+* Copyright (c) 2003, Peter Strand <peter at zarquon.se>
+*
+* This source code is released for free distribution under the terms of the
+* GNU General Public License.
+*
+* This module contains functions for generating tags for Haskell language
+* files.
+*
+*
+*
+* Does not handle operators or infix definitions like:
+* a `f` b = ...
+*
+*/
+
+
+/*
+*   INCLUDE FILES
+*/
+
+#include "general.h"	/* must always come first */
+
+#include <string.h>
+
+#include "parse.h"
+#include "read.h"
+#include "vstring.h"
+
+
+/*
+*   DATA DEFINITIONS
+*/
+typedef enum {
+    K_TYPE, K_CONSTRUCTOR, K_FUNCTION, K_MODULE
+} haskellKind;
+
+static kindOption HaskellKinds [] = {
+    { TRUE, 't', "typedef", "types" },
+    { TRUE, 'c', "macro", "type constructors" },
+    { TRUE, 'f', "function", "functions" },
+    { TRUE, 'm', "namespace", "modules"}
+};
+
+
+typedef const unsigned char *custr;
+
+/*
+*   FUNCTION DEFINITIONS
+*/
+
+
+static void skip_rest_of_line()
+{
+    int c;
+    do {
+	c = fileGetc();
+    } while (c != EOF && c != '\n');
+}
+
+static int get_line(char *buf)
+{
+    int i = 0;
+    int c;
+    do {
+        c = fileGetc();
+	buf[i++] = c;
+    } while (c != EOF && c != '\n' && i < 1000);
+    buf[i] = '\0';
+    return i;
+}
+
+static int get_next_char()
+{
+    int c, nxt;
+    c = fileGetc();
+    if (c == EOF)
+	return c;
+    nxt = fileGetc();
+    if (nxt == EOF)
+	return c;
+    fileUngetc(nxt);
+
+    if (c == '-' && nxt == '-') {
+	skip_rest_of_line();
+	return get_next_char();
+    }
+    if (c == '{' && nxt == '-') {
+	int last = '\0';
+	do {
+	    last = c;
+	    c = get_next_char();
+	} while (! (c == EOF || (last == '-' && c == '}')));
+	return get_next_char();
+    }
+    return c;
+}
+
+static void add_tag(const char *token, haskellKind kind, vString *name)
+{
+    int i;
+    for (i = 0; token[i] != '\0'; ++i)
+	vStringPut(name, token[i]);
+
+    vStringTerminate(name);
+    makeSimpleTag(name, HaskellKinds, kind);
+    vStringClear(name);
+}
+
+static int isident(char c)
+{
+    return isalnum(c) || c == '_' || c == '\'' || c == '$';
+}
+
+static int get_token(char *token, int n)
+{
+    int c = fileGetc();
+    int i = n;
+    while (c != EOF && isident(c) && i < 1000) {
+	token[i] = c;
+	i++;
+	c = fileGetc();
+    }
+    if (c == EOF)
+	return 0;
+    if (i != n) {
+	token[i] = '\0';
+	fileUngetc(c);
+	return 1;
+    } else {
+	return 0;
+    }
+}
+
+enum Find_State { Find_Eq, Find_Constr, Get_Extr, Find_Extr, Find_Bar };
+
+static int inside_datatype(vString *name)
+{
+    enum Find_State st = Find_Eq;
+    int c;
+    char token[1001];
+
+    while (1) {
+	if (st == Find_Eq)
+	{
+	    do {
+		c = get_next_char();
+		if (c == '\n') {
+		    c = get_next_char();
+		    if (! (c == ' ' || c == '\t')) {
+			return c;
+		    }
+		}
+	    } while (c != '=');
+	    st = Find_Constr;
+	}
+	else if (st == Find_Constr)
+	{
+	    do {
+		c = get_next_char();
+	    } while (isspace(c));
+	    if (!isupper(c)) {
+		    skip_rest_of_line();
+		    return '\n';
+	    }
+	    token[0] = c;
+	    if (!get_token(token, 1))
+		return '\n';
+	    add_tag(token, K_CONSTRUCTOR, name);
+	    st = Find_Extr;
+	}
+	else if (st == Find_Extr)
+	{
+	    c = get_next_char();
+    	    if (c == '{')
+		st = Get_Extr;
+	    else if (c == '|')
+		st = Find_Constr;
+	    else if (c == '\n') {
+		    c = get_next_char();
+		    if (! (c == ' ' || c == '\t')) {
+			return c;
+		    }
+	    }
+	    else if (!isspace(c))
+		st = Find_Bar;
+	}
+	else if (st == Get_Extr)
+	{
+	    do {
+		c = fileGetc();
+	    } while (isspace(c));
+	    if (c == EOF)
+		return c;
+	    token[0] = c;
+	    get_token(token, 1);
+	    add_tag(token, K_FUNCTION, name);
+	    do {
+		c = get_next_char();
+		if (c == '}') {
+		    st = Find_Bar;
+		    break;
+		}
+	    } while (c != ',');
+	}
+	else if (st == Find_Bar)
+	{
+	    do {
+		c = get_next_char();
+		if (c == '\n') {
+		    c = get_next_char();
+		    if (! (c == ' ' || c == '\t')) {
+			return c;
+		    }
+		}
+	    } while (c != EOF && c != '|');
+	    st = Find_Constr;
+	}
+    }
+    return '\n';
+}
+
+static void findHaskellTags (int is_literate)
+{
+    vString *name = vStringNew ();
+    char token[1001], arg[1001];
+    int c;
+    int in_tex_lit_code = 0;
+    c = get_next_char();
+
+    while (c != EOF)
+    {
+	if (c == '\n') {
+	    c = get_next_char();
+	    continue;
+	}
+
+	if (isspace(c)) {
+	    skip_rest_of_line();
+	    c = get_next_char();
+	    continue;
+	}
+        if (is_literate && !in_tex_lit_code) {
+            if (c == '>') {
+                c = fileGetc();
+                if (c == ' ') {
+                    c = get_next_char();
+		    if (!isident(c)) {
+			    skip_rest_of_line();
+			    c = get_next_char();
+			    continue;
+		    }
+                } else {
+                    skip_rest_of_line();
+                    c = get_next_char();
+                    continue;
+                }
+            } else if (c == '\\') {
+                int n = get_line(token);
+                if (strncmp(token, "begin{code}", 11) == 0) {
+                    in_tex_lit_code = 1;
+                    c = get_next_char();
+                    continue;
+		} else {
+		    if (n > 0 && token[n-1] != '\n')
+			skip_rest_of_line();
+		    else
+			c = get_next_char();
+		}
+		continue;
+            } else {
+                skip_rest_of_line();
+                c = get_next_char();
+                continue;
+            }
+        }
+        if (is_literate && in_tex_lit_code && c == '\\') {
+            if (strncmp(token, "end{code}", 9) == 0) {
+                in_tex_lit_code = 0;
+                c = get_next_char();
+                continue;
+            }
+        }
+	token[0] = c;
+	token[1] = '\0';
+	if (!isident(c)) {
+		skip_rest_of_line();
+		c = get_next_char();
+		continue;
+	}
+	if (!get_token(token, 1)) {
+		c = get_next_char();
+		continue;
+	}
+	do {
+	    if ((c = fileGetc()) == EOF)
+		return;
+	} while (c == ' ' || c == '\t');
+	arg[0] = c;
+	get_token(arg, 1);
+	if (strcmp(token, "data") == 0 || strcmp(token, "newtype") == 0) {
+	    add_tag(arg, K_TYPE, name);
+	    c = inside_datatype(name);
+	    continue;
+	}
+	if (strcmp(token, "type") == 0)
+	    add_tag(arg, K_TYPE, name);
+	else if (strcmp(token, "module") == 0)
+	    add_tag(arg, K_MODULE, name);
+	else if (strcmp(token, "instance") == 0 ||
+		 strcmp(token, "foreign") == 0 ||
+		 strcmp(token, "import") == 0)
+	    ;
+	else {
+	    if (arg[0] != ':')
+		add_tag(token, K_FUNCTION, name);
+	}
+	skip_rest_of_line();
+	c = get_next_char();
+    }
+    vStringDelete(name);
+}
+
+static void findNormalHaskellTags (void)
+{
+    findHaskellTags (0);
+}
+
+static void findLiterateHaskellTags (void)
+{
+    findHaskellTags (1);
+}
+
+extern parserDefinition* HaskellParser (void)
+{
+    static const char *const extensions [] = { "hs", NULL };
+    parserDefinition* def  = parserNew ("Haskell");
+
+    def->kinds      = HaskellKinds;
+    def->kindCount  = KIND_COUNT(HaskellKinds);
+    def->extensions = extensions;
+    def->parser     = findNormalHaskellTags;
+    return def;
+}
+
+extern parserDefinition* LiterateHaskellParser (void)
+{
+    static const char *const extensions [] = { "lhs", NULL };
+    parserDefinition* def = parserNew ("Literate Haskell");
+    def->kinds      = HaskellKinds;
+    def->kindCount  = KIND_COUNT(HaskellKinds);
+    def->extensions = extensions;
+    def->parser     = findLiterateHaskellTags;
+    return def;
+}
+
+/* vi:set expandtab tabstop=8 shiftwidth=4: */


Property changes on: trunk/tagmanager/haskell.c
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Modified: trunk/tagmanager/makefile.win32
===================================================================
--- trunk/tagmanager/makefile.win32	2007-05-22 15:31:40 UTC (rev 1557)
+++ trunk/tagmanager/makefile.win32	2007-05-23 12:32:06 UTC (rev 1558)
@@ -33,7 +33,7 @@
 	-$(RM) deps.mak *.o $(COMPLIB)
 
 $(COMPLIB): args.o c.o fortran.o make.o conf.o pascal.o perl.o php.o diff.o vhdl.o lua.o js.o \
-python.o regex.o sh.o ctags.o entry.o get.o keyword.o options.o parse.o \
+haskell.o python.o regex.o sh.o ctags.o entry.o get.o keyword.o options.o parse.o \
 read.o sort.o strlist.o latex.o docbook.o tcl.o ruby.o asm.o sql.o css.o vstring.o tm_workspace.o tm_work_object.o \
 tm_source_file.o tm_project.o tm_tag.o tm_symbol.o tm_file_entry.o \
 tm_tagmanager.o

Modified: trunk/tagmanager/parsers.h
===================================================================
--- trunk/tagmanager/parsers.h	2007-05-22 15:31:40 UTC (rev 1557)
+++ trunk/tagmanager/parsers.h	2007-05-23 12:32:06 UTC (rev 1558)
@@ -38,7 +38,8 @@
     DiffParser, \
     VhdlParser, \
     LuaParser, \
-    JavaScriptParser
+    JavaScriptParser, \
+    HaskellParser
 
 /*
 langType of each parser
@@ -66,6 +67,7 @@
 21	VhdlParser
 22	LuaParser
 23	JavaScriptParser
+24	HaskellParser
 */
 #endif	/* _PARSERS_H */
 


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