Branch: refs/heads/master Author: Beng Tan bengtan@users.noreply.github.com Committer: Beng Tan bengtan@users.noreply.github.com Date: Sun, 15 Mar 2015 05:41:23 UTC Commit: b0c5d221a5ef2f52a485b1d686f9c65a01efe533 https://github.com/geany/geany/commit/b0c5d221a5ef2f52a485b1d686f9c65a01efe5...
Log Message: ----------- Implement Erlang ctags.
Using erlang.c from fishman/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 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', "record", "record definitions"}, + {TRUE, 't', "type", "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 \ +$(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 \ 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: 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).