Branch: refs/heads/master Author: Colomban Wendling ban@herbesfolles.org Committer: Colomban Wendling ban@herbesfolles.org Date: Fri, 27 Mar 2015 13:44:55 UTC Commit: ca02c593e732c27c91cbf072abd798246d867d30 https://github.com/geany/geany/commit/ca02c593e732c27c91cbf072abd798246d867d...
Log Message: ----------- Merge pull request #445 from bengtan/erlang-fishman-ctags
Implement Erlang ctags
Modified Paths: -------------- src/filetypes.c tagmanager/ctags/Makefile.am tagmanager/ctags/erlang.c tagmanager/ctags/makefile.win32 tagmanager/ctags/parsers.h tagmanager/src/tm_parser.h tests/ctags/Makefile.am tests/ctags/maze.erl.tags tests/ctags/test.erl tests/ctags/test.erl.tags wscript
Modified: src/filetypes.c 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -172,7 +172,7 @@ static void init_builtin_filetypes(void) FT_INIT( VERILOG, VERILOG, "Verilog", NULL, SOURCE_FILE, COMPILED ); FT_INIT( DIFF, DIFF, "Diff", NULL, FILE, MISC ); FT_INIT( LISP, NONE, "Lisp", NULL, SOURCE_FILE, SCRIPT ); - FT_INIT( ERLANG, NONE, "Erlang", NULL, SOURCE_FILE, COMPILED ); + FT_INIT( ERLANG, ERLANG, "Erlang", NULL, SOURCE_FILE, COMPILED ); FT_INIT( CONF, CONF, "Conf", _("Config"), FILE, MISC ); FT_INIT( PO, NONE, "Po", _("Gettext translation"), FILE, MISC ); FT_INIT( HAXE, HAXE, "Haxe", NULL, SOURCE_FILE, COMPILED );
Modified: tagmanager/ctags/Makefile.am 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -23,6 +23,7 @@ parsers = \ css.c \ diff.c \ docbook.c \ + erlang.c \ fortran.c \ go.c \ haskell.c \
Modified: tagmanager/ctags/erlang.c 194 lines changed, 194 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,194 @@ +/* +* Copyright (c) 2003, Brent Fulgham bfulgham@debian.org +* +* 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 Erlang language +* files. Some of the parsing constructs are based on the Emacs 'etags' +* program by Francesco Potori pot@gnu.org +*/ +/* +* INCLUDE FILES +*/ +#include "general.h" /* must always come first */ + +#include <string.h> + +#include "entry.h" +#include "options.h" +#include "read.h" +// #include "routines.h" +#include "vstring.h" + +/* +* DATA DEFINITIONS +*/ +typedef enum { + K_MACRO, K_FUNCTION, K_MODULE, K_RECORD, K_TYPE +} erlangKind; + +static kindOption ErlangKinds[] = { + {TRUE, 'd', "macro", "macro definitions"}, + {TRUE, 'f', "function", "functions"}, + {TRUE, 'm', "module", "modules"}, + {TRUE, 'r', "struct", "record definitions"}, + {TRUE, 't', "typedef", "type definitions"}, +}; + +/* +* FUNCTION DEFINITIONS +*/ +/* tagEntryInfo and vString should be preinitialized/preallocated but not + * necessary. If successful you will find class name in vString + */ + +static boolean isIdentifierFirstCharacter (int c) +{ + return (boolean) (isalpha (c)); +} + +static boolean isIdentifierCharacter (int c) +{ + return (boolean) (isalnum (c) || c == '_' || c == ':'); +} + +static const unsigned char *skipSpace (const unsigned char *cp) +{ + while (isspace ((int) *cp)) + ++cp; + return cp; +} + +static const unsigned char *parseIdentifier ( + const unsigned char *cp, vString *const identifier) +{ + vStringClear (identifier); + while (isIdentifierCharacter ((int) *cp)) + { + vStringPut (identifier, (int) *cp); + ++cp; + } + vStringTerminate (identifier); + return cp; +} + +static void makeMemberTag ( + vString *const identifier, erlangKind kind, vString *const module) +{ + if (ErlangKinds [kind].enabled && vStringLength (identifier) > 0) + { + tagEntryInfo tag; + initTagEntry (&tag, vStringValue (identifier)); + tag.kindName = ErlangKinds[kind].name; + tag.kind = ErlangKinds[kind].letter; + + if (module != NULL && vStringLength (module) > 0) + { + tag.extensionFields.scope [0] = "module"; + tag.extensionFields.scope [1] = vStringValue (module); + } + makeTagEntry (&tag); + } +} + +static void parseModuleTag (const unsigned char *cp, vString *const module) +{ + vString *const identifier = vStringNew (); + parseIdentifier (cp, identifier); + makeSimpleTag (identifier, ErlangKinds, K_MODULE); + + /* All further entries go in the new module */ + vStringCopy (module, identifier); + vStringDelete (identifier); +} + +static void parseSimpleTag (const unsigned char *cp, erlangKind kind) +{ + vString *const identifier = vStringNew (); + parseIdentifier (cp, identifier); + makeSimpleTag (identifier, ErlangKinds, kind); + vStringDelete (identifier); +} + +static void parseFunctionTag (const unsigned char *cp, vString *const module) +{ + vString *const identifier = vStringNew (); + parseIdentifier (cp, identifier); + makeMemberTag (identifier, K_FUNCTION, module); + vStringDelete (identifier); +} + +/* + * Directives are of the form: + * -module(foo) + * -define(foo, bar) + * -record(graph, {vtab = notable, cyclic = true}). + * -type some_type() :: any(). + * -opaque some_opaque_type() :: any(). + */ +static void parseDirective (const unsigned char *cp, vString *const module) +{ + /* + * A directive will be either a record definition or a directive. + * Record definitions are handled separately + */ + vString *const directive = vStringNew (); + const char *const drtv = vStringValue (directive); + cp = parseIdentifier (cp, directive); + cp = skipSpace (cp); + if (*cp == '(') + ++cp; + + if (strcmp (drtv, "record") == 0) + parseSimpleTag (cp, K_RECORD); + else if (strcmp (drtv, "define") == 0) + parseSimpleTag (cp, K_MACRO); + else if (strcmp (drtv, "type") == 0) + parseSimpleTag (cp, K_TYPE); + else if (strcmp (drtv, "opaque") == 0) + parseSimpleTag (cp, K_TYPE); + else if (strcmp (drtv, "module") == 0) + parseModuleTag (cp, module); + /* Otherwise, it was an import, export, etc. */ + + vStringDelete (directive); +} + +static void findErlangTags (void) +{ + vString *const module = vStringNew (); + const unsigned char *line; + + while ((line = fileReadLine ()) != NULL) + { + const unsigned char *cp = line; + + if (*cp == '%') /* skip initial comment */ + continue; + if (*cp == '"') /* strings sometimes start in column one */ + continue; + + if ( *cp == '-') + { + ++cp; /* Move off of the '-' */ + parseDirective(cp, module); + } + else if (isIdentifierFirstCharacter ((int) *cp)) + parseFunctionTag (cp, module); + } + vStringDelete (module); +} + +extern parserDefinition *ErlangParser (void) +{ + static const char *const extensions[] = { "erl", "ERL", "hrl", "HRL", NULL }; + parserDefinition *def = parserNew ("Erlang"); + def->kinds = ErlangKinds; + def->kindCount = KIND_COUNT (ErlangKinds); + def->extensions = extensions; + def->parser = findErlangTags; + return def; +} + +/* vi:set tabstop=4 shiftwidth=4: */
Modified: tagmanager/ctags/makefile.win32 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -44,7 +44,7 @@ all: $(COMPLIB) clean: -$(RM) deps.mak *.o $(COMPLIB)
-$(COMPLIB): abaqus.o abc.o args.o c.o cobol.o fortran.o make.o conf.o pascal.o perl.o php.o diff.o vhdl.o verilog.o lua.o js.o json.o \ +$(COMPLIB): abaqus.o abc.o args.o c.o cobol.o erlang.o fortran.o make.o conf.o pascal.o perl.o php.o diff.o vhdl.o verilog.o lua.o js.o json.o \ actionscript.o nsis.o objc.o \ haskell.o haxe.o html.o python.o lregex.o asciidoc.o rest.o sh.o ctags.o entry.o get.o keyword.o nestlevel.o \ options.o \
Modified: tagmanager/ctags/parsers.h 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -29,6 +29,7 @@ ConfParser, \ SqlParser, \ DocBookParser, \ + ErlangParser, \ CssParser, \ RubyParser, \ TclParser, \
Modified: tagmanager/src/tm_parser.h 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -35,6 +35,7 @@ typedef enum TM_PARSER_CONF, TM_PARSER_SQL, TM_PARSER_DOCBOOK, + TM_PARSER_ERLANG, TM_PARSER_CSS, TM_PARSER_RUBY, TM_PARSER_TCL,
Modified: tests/ctags/Makefile.am 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -270,6 +270,7 @@ test_sources = \ strings.rb \ structure.f \ tabindent.py \ + test.erl \ test.go \ test.py \ test.vhd \
Modified: tests/ctags/maze.erl.tags 15 lines changed, 10 insertions(+), 5 deletions(-) =================================================================== @@ -1,6 +1,11 @@ # format=tagmanager -Acc�16384�0�a -seed�16�()�0�using random -seed�1024�(S,M,H)�0�random -tot_print�16�(Tot)�0� -uniform�16384�0�pick pick +build�16�maze�0 +generate�16�maze�0 +pick�16�maze�0 +scramble�16�maze�0 +seed�16�maze�0 +tot_get�16�maze�0 +tot_new�16�maze�0 +tot_print�16�maze�0 +tot_print_tuple�16�maze�0 +tot_put�16�maze�0
Modified: tests/ctags/test.erl 16 lines changed, 16 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,16 @@ +-module(test). + +-export([function1/0, function1/2]). + +-type type1() :: binary(). + +-record(record1, {name :: list(), value :: list()}). + +-define(DEFINE_1, function1()). +-define(DEFINE_2(A, B), function2(A, B)). + +function1() -> + ok. + +function1(A, B) -> + A + B.
Modified: tests/ctags/test.erl.tags 6 lines changed, 6 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,6 @@ +# format=tagmanager +DEFINE_1�65536�0 +DEFINE_2�65536�0 +function1�16�test�0 +record1�2048�0 +type1�4096�0
Modified: wscript 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -79,6 +79,7 @@ ctags_sources = set([ 'tagmanager/ctags/ctags.c', 'tagmanager/ctags/diff.c', 'tagmanager/ctags/docbook.c', + 'tagmanager/ctags/erlang.c', 'tagmanager/ctags/entry.c', 'tagmanager/ctags/fortran.c', 'tagmanager/ctags/get.c',
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).