Skip to content

Instantly share code, notes, and snippets.

@codebrainz
Created March 21, 2012 22:29
Show Gist options
  • Save codebrainz/2153795 to your computer and use it in GitHub Desktop.
Save codebrainz/2153795 to your computer and use it in GitHub Desktop.
CTAGS - Add D, GLSL, Ferite and Vala support (untested)
Index: parsers.h
===================================================================
--- parsers.h (revision 781)
+++ parsers.h (working copy)
@@ -26,11 +26,14 @@
CppParser, \
CsharpParser, \
CobolParser, \
+ DParser, \
DosBatchParser, \
EiffelParser, \
ErlangParser, \
+ FeriteParser, \
FlexParser, \
FortranParser, \
+ GLSLParser, \
HtmlParser, \
JavaParser, \
JavaScriptParser, \
@@ -53,6 +56,7 @@
SqlParser, \
TclParser, \
TexParser, \
+ ValaParser, \
VeraParser, \
VerilogParser, \
VhdlParser, \
Index: c.c
===================================================================
--- c.c (revision 781)
+++ c.c (working copy)
@@ -2,11 +2,12 @@
* $Id$
*
* Copyright (c) 1996-2003, Darren Hiebert
+* Copyright (c) 2012, Matthew Brush
*
* This source code is released for free distribution under the terms of the
* GNU General Public License.
*
-* This module contains functions for parsing and scanning C, C++ and Java
+* This module contains functions for parsing and scanning C, C++, D, Java and Vala
* source files.
*/
@@ -48,7 +49,7 @@
* DATA DECLARATIONS
*/
-enum { NumTokens = 3 };
+enum { NumTokens = 12 };
typedef enum eException {
ExceptionNone, ExceptionEOF, ExceptionFormattingError,
@@ -59,31 +60,31 @@
*/
typedef enum eKeywordId {
KEYWORD_NONE = -1,
- KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT,
+ KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT, KEYWORD_ALIAS,
KEYWORD_BOOLEAN, KEYWORD_BYTE, KEYWORD_BAD_STATE, KEYWORD_BAD_TRANS,
- KEYWORD_BIND, KEYWORD_BIND_VAR, KEYWORD_BIT,
+ KEYWORD_BIND, KEYWORD_BIND_VAR, KEYWORD_BIT, KEYWORD_BODY,
KEYWORD_CASE, KEYWORD_CATCH, KEYWORD_CHAR, KEYWORD_CLASS, KEYWORD_CONST,
KEYWORD_CONSTRAINT, KEYWORD_COVERAGE_BLOCK, KEYWORD_COVERAGE_DEF,
KEYWORD_DEFAULT, KEYWORD_DELEGATE, KEYWORD_DELETE, KEYWORD_DO,
KEYWORD_DOUBLE,
KEYWORD_ELSE, KEYWORD_ENUM, KEYWORD_EXPLICIT, KEYWORD_EXTERN,
KEYWORD_EXTENDS, KEYWORD_EVENT,
- KEYWORD_FINAL, KEYWORD_FLOAT, KEYWORD_FOR, KEYWORD_FOREACH,
+ KEYWORD_FINAL, KEYWORD_FINALLY, KEYWORD_FLOAT, KEYWORD_FOR, KEYWORD_FOREACH,
KEYWORD_FRIEND, KEYWORD_FUNCTION,
- KEYWORD_GOTO,
- KEYWORD_IF, KEYWORD_IMPLEMENTS, KEYWORD_IMPORT, KEYWORD_INLINE, KEYWORD_INT,
+ KEYWORD_GET, KEYWORD_GOTO,
+ KEYWORD_IF, KEYWORD_IMPLEMENTS, KEYWORD_IMPORT, KEYWORD_IN, KEYWORD_INLINE, KEYWORD_INT,
KEYWORD_INOUT, KEYWORD_INPUT, KEYWORD_INTEGER, KEYWORD_INTERFACE,
KEYWORD_INTERNAL,
KEYWORD_LOCAL, KEYWORD_LONG,
KEYWORD_M_BAD_STATE, KEYWORD_M_BAD_TRANS, KEYWORD_M_STATE, KEYWORD_M_TRANS,
- KEYWORD_MUTABLE,
+ KEYWORD_MODULE, KEYWORD_MUTABLE,
KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NEWCOV, KEYWORD_NATIVE,
- KEYWORD_OPERATOR, KEYWORD_OUTPUT, KEYWORD_OVERLOAD, KEYWORD_OVERRIDE,
+ KEYWORD_OPERATOR, KEYWORD_OUT, KEYWORD_OUTPUT, KEYWORD_OVERLOAD, KEYWORD_OVERRIDE,
KEYWORD_PACKED, KEYWORD_PORT, KEYWORD_PACKAGE, KEYWORD_PRIVATE,
KEYWORD_PROGRAM, KEYWORD_PROTECTED, KEYWORD_PUBLIC,
- KEYWORD_REGISTER, KEYWORD_RETURN,
+ KEYWORD_REF, KEYWORD_REGISTER, KEYWORD_RETURN,
KEYWORD_SHADOW, KEYWORD_STATE,
- KEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STRING,
+ KEYWORD_SET, KEYWORD_SHORT, KEYWORD_SIGNAL, KEYWORD_SIGNED, KEYWORD_SIZE_T, KEYWORD_STATIC, KEYWORD_STRING,
KEYWORD_STRUCT, KEYWORD_SWITCH, KEYWORD_SYNCHRONIZED,
KEYWORD_TASK, KEYWORD_TEMPLATE, KEYWORD_THIS, KEYWORD_THROW,
KEYWORD_THROWS, KEYWORD_TRANSIENT, KEYWORD_TRANS, KEYWORD_TRANSITION,
@@ -91,7 +92,7 @@
KEYWORD_UINT, KEYWORD_ULONG, KEYWORD_UNION, KEYWORD_UNSIGNED, KEYWORD_USHORT,
KEYWORD_USING,
KEYWORD_VIRTUAL, KEYWORD_VOID, KEYWORD_VOLATILE,
- KEYWORD_WCHAR_T, KEYWORD_WHILE
+ KEYWORD_WCHAR_T, KEYWORD_WEAK, KEYWORD_WHILE
} keywordId;
/* Used to determine whether keyword is valid for the current language and
@@ -100,7 +101,7 @@
typedef struct sKeywordDesc {
const char *name;
keywordId id;
- short isValid [5]; /* indicates languages for which kw is valid */
+ short isValid [7]; /* indicates languages for which kw is valid */
} keywordDesc;
/* Used for reporting the type of object parsed by nextToken ().
@@ -114,11 +115,13 @@
TOKEN_COMMA, /* the comma character */
TOKEN_DOUBLE_COLON, /* double colon indicates nested-name-specifier */
TOKEN_KEYWORD,
- TOKEN_NAME, /* an unknown name */
- TOKEN_PACKAGE, /* a Java package name */
- TOKEN_PAREN_NAME, /* a single name in parentheses */
- TOKEN_SEMICOLON, /* the semicolon character */
- TOKEN_SPEC, /* a storage class specifier, qualifier, type, etc. */
+ TOKEN_NAME, /* an unknown name */
+ TOKEN_PACKAGE, /* a Java package name */
+ TOKEN_PAREN_NAME, /* a single name in parentheses */
+ TOKEN_SEMICOLON, /* the semicolon character */
+ TOKEN_SPEC, /* a storage class specifier, qualifier, type, etc. */
+ TOKEN_STAR, /* pointer detection */
+ TOKEN_ARRAY, /* array detection */
TOKEN_COUNT
} tokenType;
@@ -139,9 +142,12 @@
DECL_CLASS,
DECL_ENUM,
DECL_EVENT,
+ DECL_SIGNAL,
DECL_FUNCTION,
- DECL_IGNORE, /* non-taggable "declaration" */
+ DECL_FUNCTION_TEMPLATE,
+ DECL_IGNORE, /* non-taggable "declaration" */
DECL_INTERFACE,
+ DECL_MODULE,
DECL_NAMESPACE,
DECL_NOMANGLE, /* C++ name demangling block */
DECL_PACKAGE,
@@ -206,6 +212,8 @@
memberInfo member; /* information regarding parent class/struct */
vString* parentClasses; /* parent classes */
struct sStatementInfo *parent; /* statement we are nested within */
+ long argEndPosition; /* Position where argument list ended */
+ tokenInfo* firstToken; /* First token in the statement */
} statementInfo;
/* Describes the type of tag being generated.
@@ -220,6 +228,7 @@
TAG_FUNCTION, /* function definition */
TAG_INTERFACE, /* interface declaration */
TAG_LOCAL, /* local variable definition */
+ TAG_MACRO, /* #define s */
TAG_MEMBER, /* structure, class or interface member */
TAG_METHOD, /* method declaration */
TAG_NAMESPACE, /* namespace name */
@@ -227,6 +236,7 @@
TAG_PROGRAM, /* program name */
TAG_PROPERTY, /* property name */
TAG_PROTOTYPE, /* function prototype or declaration */
+ TAG_SIGNAL, /* signal */
TAG_STRUCT, /* structure name */
TAG_TASK, /* task name */
TAG_TYPEDEF, /* typedef name */
@@ -255,7 +265,11 @@
static langType Lang_c;
static langType Lang_cpp;
static langType Lang_csharp;
+static langType Lang_d;
+static langType Lang_ferite;
+static langType Lang_glsl;
static langType Lang_java;
+static langType Lang_vala;
static langType Lang_vera;
static vString *Signature;
static boolean CollectingSignature;
@@ -312,6 +326,32 @@
{ TRUE, 't', "typedef", "typedefs"},
};
+/* Used to index into the DKinds table. */
+typedef enum
+{
+ DK_UNDEFINED = -1,
+ DK_CLASS, DK_ENUMERATOR, DK_FUNCTION,
+ DK_ENUMERATION, DK_INTERFACE, DK_MEMBER, DK_NAMESPACE, DK_PROTOTYPE,
+ DK_STRUCT, DK_TYPEDEF, DK_UNION, DK_VARIABLE,
+ DK_EXTERN_VARIABLE
+} dKind;
+
+static kindOption DKinds [] = {
+ { TRUE, 'c', "class", "classes"},
+ { TRUE, 'e', "enumerator", "enumerators (values inside an enumeration)"},
+ { TRUE, 'f', "function", "function definitions"},
+ { TRUE, 'g', "enum", "enumeration names"},
+ { TRUE, 'i', "interface", "interfaces"},
+ { TRUE, 'm', "member", "class, struct, and union members"},
+ { TRUE, 'n', "namespace", "namespaces"},
+ { FALSE, 'p', "prototype", "function prototypes"},
+ { TRUE, 's', "struct", "structure names"},
+ { TRUE, 't', "typedef", "typedefs"},
+ { TRUE, 'u', "union", "union names"},
+ { TRUE, 'v', "variable", "variable definitions"},
+ { FALSE, 'x', "externvar", "external variable declarations"},
+};
+
/* Used to index into the JavaKinds table. */
typedef enum {
JK_UNDEFINED = -1,
@@ -330,6 +370,28 @@
{ TRUE, 'p', "package", "packages"},
};
+typedef enum {
+ VAK_UNDEFINED = -1,
+ VAK_CLASS, VAK_DEFINE, VAK_ENUMERATOR, VAK_FIELD,
+ VAK_ENUMERATION, VAK_INTERFACE, VAK_LOCAL, VAK_METHOD,
+ VAK_NAMESPACE, VAK_PROPERTY, VAK_SIGNAL, VAK_STRUCT
+} valaKind;
+
+static kindOption ValaKinds [] = {
+ { TRUE, 'c', "class", "classes"},
+ { TRUE, 'd', "macro", "macro definitions"},
+ { TRUE, 'e', "enumerator", "enumerators (values inside an enumeration)"},
+ { TRUE, 'f', "field", "fields"},
+ { TRUE, 'g', "enum", "enumeration names"},
+ { TRUE, 'i', "interface", "interfaces"},
+ { FALSE, 'l', "local", "local variables"},
+ { TRUE, 'm', "method", "methods"},
+ { TRUE, 'n', "namespace", "namespaces"},
+ { TRUE, 'p', "property", "properties"},
+ { TRUE, 'S', "signal", "signals"},
+ { TRUE, 's', "struct", "structure names"},
+};
+
/* Used to index into the VeraKinds table. */
typedef enum {
VK_UNDEFINED = -1,
@@ -356,116 +418,139 @@
};
static const keywordDesc KeywordTable [] = {
- /* C++ */
- /* ANSI C | C# Java */
- /* | | | | Vera */
- /* keyword keyword ID | | | | | */
- { "__attribute__", KEYWORD_ATTRIBUTE, { 1, 1, 1, 0, 0 } },
- { "abstract", KEYWORD_ABSTRACT, { 0, 0, 1, 1, 0 } },
- { "bad_state", KEYWORD_BAD_STATE, { 0, 0, 0, 0, 1 } },
- { "bad_trans", KEYWORD_BAD_TRANS, { 0, 0, 0, 0, 1 } },
- { "bind", KEYWORD_BIND, { 0, 0, 0, 0, 1 } },
- { "bind_var", KEYWORD_BIND_VAR, { 0, 0, 0, 0, 1 } },
- { "bit", KEYWORD_BIT, { 0, 0, 0, 0, 1 } },
- { "boolean", KEYWORD_BOOLEAN, { 0, 0, 0, 1, 0 } },
- { "byte", KEYWORD_BYTE, { 0, 0, 0, 1, 0 } },
- { "case", KEYWORD_CASE, { 1, 1, 1, 1, 0 } },
- { "catch", KEYWORD_CATCH, { 0, 1, 1, 0, 0 } },
- { "char", KEYWORD_CHAR, { 1, 1, 1, 1, 0 } },
- { "class", KEYWORD_CLASS, { 0, 1, 1, 1, 1 } },
- { "const", KEYWORD_CONST, { 1, 1, 1, 1, 0 } },
- { "constraint", KEYWORD_CONSTRAINT, { 0, 0, 0, 0, 1 } },
- { "coverage_block", KEYWORD_COVERAGE_BLOCK, { 0, 0, 0, 0, 1 } },
- { "coverage_def", KEYWORD_COVERAGE_DEF, { 0, 0, 0, 0, 1 } },
- { "do", KEYWORD_DO, { 1, 1, 1, 1, 0 } },
- { "default", KEYWORD_DEFAULT, { 1, 1, 1, 1, 0 } },
- { "delegate", KEYWORD_DELEGATE, { 0, 0, 1, 0, 0 } },
- { "delete", KEYWORD_DELETE, { 0, 1, 0, 0, 0 } },
- { "double", KEYWORD_DOUBLE, { 1, 1, 1, 1, 0 } },
- { "else", KEYWORD_ELSE, { 1, 1, 1, 1, 0 } },
- { "enum", KEYWORD_ENUM, { 1, 1, 1, 1, 1 } },
- { "event", KEYWORD_EVENT, { 0, 0, 1, 0, 1 } },
- { "explicit", KEYWORD_EXPLICIT, { 0, 1, 1, 0, 0 } },
- { "extends", KEYWORD_EXTENDS, { 0, 0, 0, 1, 1 } },
- { "extern", KEYWORD_EXTERN, { 1, 1, 1, 0, 1 } },
- { "final", KEYWORD_FINAL, { 0, 0, 0, 1, 0 } },
- { "float", KEYWORD_FLOAT, { 1, 1, 1, 1, 0 } },
- { "for", KEYWORD_FOR, { 1, 1, 1, 1, 0 } },
- { "foreach", KEYWORD_FOREACH, { 0, 0, 1, 0, 0 } },
- { "friend", KEYWORD_FRIEND, { 0, 1, 0, 0, 0 } },
- { "function", KEYWORD_FUNCTION, { 0, 0, 0, 0, 1 } },
- { "goto", KEYWORD_GOTO, { 1, 1, 1, 1, 0 } },
- { "if", KEYWORD_IF, { 1, 1, 1, 1, 0 } },
- { "implements", KEYWORD_IMPLEMENTS, { 0, 0, 0, 1, 0 } },
- { "import", KEYWORD_IMPORT, { 0, 0, 0, 1, 0 } },
- { "inline", KEYWORD_INLINE, { 0, 1, 0, 0, 0 } },
- { "inout", KEYWORD_INOUT, { 0, 0, 0, 0, 1 } },
- { "input", KEYWORD_INPUT, { 0, 0, 0, 0, 1 } },
- { "int", KEYWORD_INT, { 1, 1, 1, 1, 0 } },
- { "integer", KEYWORD_INTEGER, { 0, 0, 0, 0, 1 } },
- { "interface", KEYWORD_INTERFACE, { 0, 0, 1, 1, 1 } },
- { "internal", KEYWORD_INTERNAL, { 0, 0, 1, 0, 0 } },
- { "local", KEYWORD_LOCAL, { 0, 0, 0, 0, 1 } },
- { "long", KEYWORD_LONG, { 1, 1, 1, 1, 0 } },
- { "m_bad_state", KEYWORD_M_BAD_STATE, { 0, 0, 0, 0, 1 } },
- { "m_bad_trans", KEYWORD_M_BAD_TRANS, { 0, 0, 0, 0, 1 } },
- { "m_state", KEYWORD_M_STATE, { 0, 0, 0, 0, 1 } },
- { "m_trans", KEYWORD_M_TRANS, { 0, 0, 0, 0, 1 } },
- { "mutable", KEYWORD_MUTABLE, { 0, 1, 0, 0, 0 } },
- { "namespace", KEYWORD_NAMESPACE, { 0, 1, 1, 0, 0 } },
- { "native", KEYWORD_NATIVE, { 0, 0, 0, 1, 0 } },
- { "new", KEYWORD_NEW, { 0, 1, 1, 1, 0 } },
- { "newcov", KEYWORD_NEWCOV, { 0, 0, 0, 0, 1 } },
- { "operator", KEYWORD_OPERATOR, { 0, 1, 1, 0, 0 } },
- { "output", KEYWORD_OUTPUT, { 0, 0, 0, 0, 1 } },
- { "overload", KEYWORD_OVERLOAD, { 0, 1, 0, 0, 0 } },
- { "override", KEYWORD_OVERRIDE, { 0, 0, 1, 0, 0 } },
- { "package", KEYWORD_PACKAGE, { 0, 0, 0, 1, 0 } },
- { "packed", KEYWORD_PACKED, { 0, 0, 0, 0, 1 } },
- { "port", KEYWORD_PORT, { 0, 0, 0, 0, 1 } },
- { "private", KEYWORD_PRIVATE, { 0, 1, 1, 1, 0 } },
- { "program", KEYWORD_PROGRAM, { 0, 0, 0, 0, 1 } },
- { "protected", KEYWORD_PROTECTED, { 0, 1, 1, 1, 1 } },
- { "public", KEYWORD_PUBLIC, { 0, 1, 1, 1, 1 } },
- { "register", KEYWORD_REGISTER, { 1, 1, 0, 0, 0 } },
- { "return", KEYWORD_RETURN, { 1, 1, 1, 1, 0 } },
- { "shadow", KEYWORD_SHADOW, { 0, 0, 0, 0, 1 } },
- { "short", KEYWORD_SHORT, { 1, 1, 1, 1, 0 } },
- { "signed", KEYWORD_SIGNED, { 1, 1, 0, 0, 0 } },
- { "state", KEYWORD_STATE, { 0, 0, 0, 0, 1 } },
- { "static", KEYWORD_STATIC, { 1, 1, 1, 1, 1 } },
- { "string", KEYWORD_STRING, { 0, 0, 1, 0, 1 } },
- { "struct", KEYWORD_STRUCT, { 1, 1, 1, 0, 0 } },
- { "switch", KEYWORD_SWITCH, { 1, 1, 1, 1, 0 } },
- { "synchronized", KEYWORD_SYNCHRONIZED, { 0, 0, 0, 1, 0 } },
- { "task", KEYWORD_TASK, { 0, 0, 0, 0, 1 } },
- { "template", KEYWORD_TEMPLATE, { 0, 1, 0, 0, 0 } },
- { "this", KEYWORD_THIS, { 0, 1, 1, 1, 0 } },
- { "throw", KEYWORD_THROW, { 0, 1, 1, 1, 0 } },
- { "throws", KEYWORD_THROWS, { 0, 0, 0, 1, 0 } },
- { "trans", KEYWORD_TRANS, { 0, 0, 0, 0, 1 } },
- { "transition", KEYWORD_TRANSITION, { 0, 0, 0, 0, 1 } },
- { "transient", KEYWORD_TRANSIENT, { 0, 0, 0, 1, 0 } },
- { "try", KEYWORD_TRY, { 0, 1, 1, 0, 0 } },
- { "typedef", KEYWORD_TYPEDEF, { 1, 1, 1, 0, 1 } },
- { "typename", KEYWORD_TYPENAME, { 0, 1, 0, 0, 0 } },
- { "uint", KEYWORD_UINT, { 0, 0, 1, 0, 0 } },
- { "ulong", KEYWORD_ULONG, { 0, 0, 1, 0, 0 } },
- { "union", KEYWORD_UNION, { 1, 1, 0, 0, 0 } },
- { "unsigned", KEYWORD_UNSIGNED, { 1, 1, 1, 0, 0 } },
- { "ushort", KEYWORD_USHORT, { 0, 0, 1, 0, 0 } },
- { "using", KEYWORD_USING, { 0, 1, 1, 0, 0 } },
- { "virtual", KEYWORD_VIRTUAL, { 0, 1, 1, 0, 1 } },
- { "void", KEYWORD_VOID, { 1, 1, 1, 1, 1 } },
- { "volatile", KEYWORD_VOLATILE, { 1, 1, 1, 1, 0 } },
- { "wchar_t", KEYWORD_WCHAR_T, { 1, 1, 1, 0, 0 } },
- { "while", KEYWORD_WHILE, { 1, 1, 1, 1, 0 } }
+ /* C++ */
+ /* ANSI C | C# Java */
+ /* | | | | Vera */
+ /* | | | | | Vala */
+ /* | | | | | | D */
+ /* keyword keyword ID | | | | | | | */
+ { "__attribute__", KEYWORD_ATTRIBUTE, { 1, 1, 1, 0, 0, 0, 1 } },
+ { "abstract", KEYWORD_ABSTRACT, { 0, 0, 1, 1, 0, 1, 1 } },
+ { "alias", KEYWORD_TYPEDEF, { 0, 0, 0, 0, 0, 0, 1 } }, /* handle like typedef */
+ { "bad_state", KEYWORD_BAD_STATE, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "bad_trans", KEYWORD_BAD_TRANS, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "bind", KEYWORD_BIND, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "bind_var", KEYWORD_BIND_VAR, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "bit", KEYWORD_BIT, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "body", KEYWORD_BODY, { 0, 0, 0, 0, 0, 0, 1 } },
+ { "boolean", KEYWORD_BOOLEAN, { 0, 0, 0, 1, 0, 0, 0 } },
+ { "byte", KEYWORD_BYTE, { 0, 0, 0, 1, 0, 0, 1 } },
+ { "case", KEYWORD_CASE, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "catch", KEYWORD_CATCH, { 0, 1, 1, 0, 0, 1, 1 } },
+ { "char", KEYWORD_CHAR, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "class", KEYWORD_CLASS, { 0, 1, 1, 1, 1, 1, 1 } },
+ { "const", KEYWORD_CONST, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "constraint", KEYWORD_CONSTRAINT, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "coverage_block", KEYWORD_COVERAGE_BLOCK, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "coverage_def", KEYWORD_COVERAGE_DEF, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "do", KEYWORD_DO, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "default", KEYWORD_DEFAULT, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "delegate", KEYWORD_DELEGATE, { 0, 0, 1, 0, 0, 1, 1 } },
+ { "delete", KEYWORD_DELETE, { 0, 1, 0, 0, 0, 1, 1 } },
+ { "double", KEYWORD_DOUBLE, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "else", KEYWORD_ELSE, { 1, 1, 0, 1, 0, 1, 1 } },
+ { "ensures", KEYWORD_ATTRIBUTE, { 0, 0, 0, 0, 0, 1, 0 } }, /* ignore */
+ { "enum", KEYWORD_ENUM, { 1, 1, 1, 1, 1, 1, 1 } },
+ { "errordomain", KEYWORD_ENUM, { 0, 0, 0, 0, 0, 1, 0 } }, /* errordomain behaves like enum */
+ { "event", KEYWORD_EVENT, { 0, 0, 1, 0, 1, 0, 0 } },
+ { "explicit", KEYWORD_EXPLICIT, { 0, 1, 1, 0, 0, 0, 1 } },
+ { "extends", KEYWORD_EXTENDS, { 0, 0, 0, 1, 1, 0, 0 } },
+ { "extern", KEYWORD_EXTERN, { 1, 1, 1, 0, 1, 1, 0 } },
+ { "extern", KEYWORD_NAMESPACE, { 0, 0, 0, 0, 0, 0, 1 } }, /* parse block */
+ { "final", KEYWORD_FINAL, { 0, 0, 0, 1, 0, 0, 1 } },
+ { "finally", KEYWORD_FINALLY, { 0, 0, 0, 0, 0, 1, 1 } },
+ { "float", KEYWORD_FLOAT, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "for", KEYWORD_FOR, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "foreach", KEYWORD_FOREACH, { 0, 0, 1, 0, 0, 1, 1 } },
+ { "friend", KEYWORD_FRIEND, { 0, 1, 0, 0, 0, 0, 0 } },
+ { "function", KEYWORD_FUNCTION, { 0, 0, 0, 0, 1, 0, 1 } },
+ { "get", KEYWORD_GET, { 0, 0, 0, 0, 0, 1, 0 } },
+ { "goto", KEYWORD_GOTO, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "if", KEYWORD_IF, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "implements", KEYWORD_IMPLEMENTS, { 0, 0, 0, 1, 0, 0, 0 } },
+ { "import", KEYWORD_IMPORT, { 0, 0, 0, 1, 0, 0, 1 } },
+ { "inline", KEYWORD_INLINE, { 0, 1, 0, 0, 0, 1, 0 } },
+ { "in", KEYWORD_IN, { 0, 0, 0, 0, 0, 0, 1 } },
+ { "inout", KEYWORD_INOUT, { 0, 0, 0, 0, 1, 0, 1 } },
+ { "input", KEYWORD_INPUT, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "int", KEYWORD_INT, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "integer", KEYWORD_INTEGER, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "interface", KEYWORD_INTERFACE, { 0, 0, 1, 1, 1, 1, 1 } },
+ { "internal", KEYWORD_INTERNAL, { 0, 0, 1, 0, 0, 0, 0 } },
+ { "local", KEYWORD_LOCAL, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "long", KEYWORD_LONG, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "m_bad_state", KEYWORD_M_BAD_STATE, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "m_bad_trans", KEYWORD_M_BAD_TRANS, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "m_state", KEYWORD_M_STATE, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "m_trans", KEYWORD_M_TRANS, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "mutable", KEYWORD_MUTABLE, { 0, 1, 0, 0, 0, 0, 0 } },
+ { "module", KEYWORD_MODULE, { 0, 0, 0, 0, 0, 0, 1 } },
+ { "namespace", KEYWORD_NAMESPACE, { 0, 1, 1, 0, 0, 1, 0 } },
+ { "native", KEYWORD_NATIVE, { 0, 0, 0, 1, 0, 0, 0 } },
+ { "new", KEYWORD_NEW, { 0, 1, 1, 1, 0, 1, 1 } },
+ { "newcov", KEYWORD_NEWCOV, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "operator", KEYWORD_OPERATOR, { 0, 1, 1, 0, 0, 0, 0 } },
+ { "out", KEYWORD_OUT, { 0, 0, 0, 0, 0, 1, 1 } },
+ { "output", KEYWORD_OUTPUT, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "overload", KEYWORD_OVERLOAD, { 0, 1, 0, 0, 0, 0, 0 } },
+ { "override", KEYWORD_OVERRIDE, { 0, 0, 1, 0, 0, 1, 1 } },
+ { "package", KEYWORD_PACKAGE, { 0, 0, 0, 1, 0, 0, 1 } },
+ { "packed", KEYWORD_PACKED, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "port", KEYWORD_PORT, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "private", KEYWORD_PRIVATE, { 0, 1, 1, 1, 0, 1, 1 } },
+ { "program", KEYWORD_PROGRAM, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "protected", KEYWORD_PROTECTED, { 0, 1, 1, 1, 1, 1, 1 } },
+ { "public", KEYWORD_PUBLIC, { 0, 1, 1, 1, 1, 1, 1 } },
+ { "ref", KEYWORD_REF, { 0, 0, 0, 0, 0, 1, 1 } },
+ { "register", KEYWORD_REGISTER, { 1, 1, 0, 0, 0, 0, 0 } },
+ { "requires", KEYWORD_ATTRIBUTE, { 0, 0, 0, 0, 0, 1, 0 } }, /* ignore */
+ { "return", KEYWORD_RETURN, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "set", KEYWORD_SET, { 0, 0, 0, 0, 0, 1, 0 } },
+ { "shadow", KEYWORD_SHADOW, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "short", KEYWORD_SHORT, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "signal", KEYWORD_SIGNAL, { 0, 0, 0, 0, 0, 1, 0 } },
+ { "signed", KEYWORD_SIGNED, { 1, 1, 0, 0, 0, 0, 0 } },
+ { "size_t", KEYWORD_SIZE_T, { 1, 1, 0, 0, 0, 1, 1 } },
+ { "state", KEYWORD_STATE, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "static", KEYWORD_STATIC, { 1, 1, 1, 1, 1, 1, 1 } },
+ { "string", KEYWORD_STRING, { 0, 0, 1, 0, 1, 1, 0 } },
+ { "struct", KEYWORD_STRUCT, { 1, 1, 1, 0, 0, 1, 1 } },
+ { "switch", KEYWORD_SWITCH, { 1, 1, 1, 1, 0, 1, 1 } },
+ { "synchronized", KEYWORD_SYNCHRONIZED, { 0, 0, 0, 1, 0, 0, 1 } },
+ { "task", KEYWORD_TASK, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "template", KEYWORD_TEMPLATE, { 0, 1, 0, 0, 0, 0, 0 } },
+ { "template", KEYWORD_NAMESPACE, { 0, 0, 0, 0, 0, 0, 1 } }, /* parse block */
+ { "this", KEYWORD_THIS, { 0, 0, 1, 1, 0, 1, 0 } }, /* 0 to allow D ctor tags */
+ { "throw", KEYWORD_THROW, { 0, 1, 1, 1, 0, 1, 1 } },
+ { "throws", KEYWORD_THROWS, { 0, 0, 0, 1, 0, 1, 0 } },
+ { "trans", KEYWORD_TRANS, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "transition", KEYWORD_TRANSITION, { 0, 0, 0, 0, 1, 0, 0 } },
+ { "transient", KEYWORD_TRANSIENT, { 0, 0, 0, 1, 0, 0, 0 } },
+ { "try", KEYWORD_TRY, { 0, 1, 1, 0, 0, 1, 1 } },
+ { "typedef", KEYWORD_TYPEDEF, { 1, 1, 1, 0, 1, 0, 1 } },
+ { "typename", KEYWORD_TYPENAME, { 0, 1, 0, 0, 0, 0, 0 } },
+ { "uint", KEYWORD_UINT, { 0, 0, 1, 0, 0, 1, 1 } },
+ { "ulong", KEYWORD_ULONG, { 0, 0, 1, 0, 0, 1, 1 } },
+ { "union", KEYWORD_UNION, { 1, 1, 0, 0, 0, 0, 1 } },
+ { "unittest", KEYWORD_BODY, { 0, 0, 0, 0, 0, 0, 1 } }, /* ignore */
+ { "unsigned", KEYWORD_UNSIGNED, { 1, 1, 1, 0, 0, 0, 1 } },
+ { "ushort", KEYWORD_USHORT, { 0, 0, 1, 0, 0, 1, 1 } },
+ { "using", KEYWORD_USING, { 0, 1, 1, 0, 0, 1, 0 } },
+ { "version", KEYWORD_NAMESPACE, { 0, 0, 0, 0, 0, 0, 1 } }, /* parse block */
+ { "virtual", KEYWORD_VIRTUAL, { 0, 1, 1, 0, 1, 1, 0 } },
+ { "void", KEYWORD_VOID, { 1, 1, 1, 1, 1, 1, 1 } },
+ { "volatile", KEYWORD_VOLATILE, { 1, 1, 1, 1, 0, 0, 1 } },
+ { "wchar_t", KEYWORD_WCHAR_T, { 1, 1, 1, 0, 0, 0, 1 } },
+ { "weak", KEYWORD_WEAK, { 0, 0, 0, 0, 0, 1, 0 } },
+ { "while", KEYWORD_WHILE, { 1, 1, 1, 1, 0, 1, 1 } }
};
/*
* FUNCTION PROTOTYPES
*/
static void createTags (const unsigned int nestLevel, statementInfo *const parent);
+static void copyToken (tokenInfo *const dest, const tokenInfo *const src);
+static const char *getVarType (const statementInfo *const st);
/*
* FUNCTION DEFINITIONS
@@ -473,7 +558,15 @@
extern boolean includingDefineTags (void)
{
- return CKinds [CK_DEFINE].enabled;
+ if (isLanguage(Lang_c) ||
+ isLanguage(Lang_cpp) ||
+ isLanguage(Lang_csharp) ||
+ isLanguage(Lang_ferite) ||
+ isLanguage(Lang_glsl) ||
+ isLanguage(Lang_vala))
+ return CKinds [CK_DEFINE].enabled;
+
+ return FALSE;
}
/*
@@ -573,7 +666,7 @@
{
static const char *const names [] = {
"none", "args", "}", "{", "colon", "comma", "double colon", "keyword",
- "name", "package", "paren-name", "semicolon", "specifier"
+ "name", "package", "paren-name", "semicolon", "specifier", "*", "[]"
};
Assert (sizeof (names) / sizeof (names [0]) == TOKEN_COUNT);
Assert ((int) type < TOKEN_COUNT);
@@ -593,9 +686,9 @@
static const char *declString (const declType declaration)
{
static const char *const names [] = {
- "?", "base", "class", "enum", "event", "function", "ignore",
- "interface", "namespace", "no mangle", "package", "program",
- "struct", "task", "union",
+ "?", "base", "class", "enum", "event", "function", "function template",
+ "ignore", "interface", "module", "namespace", "no mangle", "package",
+ "program", "signal", "struct", "task", "union",
};
Assert (sizeof (names) / sizeof (names [0]) == DECL_COUNT);
Assert ((int) declaration < DECL_COUNT);
@@ -660,6 +753,27 @@
* Statement management
*/
+static boolean isDataTypeKeyword (const tokenInfo *const token)
+{
+ switch (token->keyword)
+ {
+ case KEYWORD_BOOLEAN:
+ case KEYWORD_BYTE:
+ case KEYWORD_CHAR:
+ case KEYWORD_DOUBLE:
+ case KEYWORD_FLOAT:
+ case KEYWORD_INT:
+ case KEYWORD_LONG:
+ case KEYWORD_SHORT:
+ case KEYWORD_VOID:
+ case KEYWORD_WCHAR_T:
+ case KEYWORD_SIZE_T:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
static boolean isContextualKeyword (const tokenInfo *const token)
{
boolean result;
@@ -682,18 +796,30 @@
static boolean isContextualStatement (const statementInfo *const st)
{
boolean result = FALSE;
- if (st != NULL) switch (st->declaration)
+
+ if (st != NULL)
{
- case DECL_CLASS:
- case DECL_ENUM:
- case DECL_INTERFACE:
- case DECL_NAMESPACE:
- case DECL_STRUCT:
- case DECL_UNION:
+ if (isLanguage (Lang_vala))
+ {
+ /* All can be a contextual statment as properties can be of any type */
result = TRUE;
- break;
+ }
+ else
+ {
+ switch (st->declaration)
+ {
+ case DECL_CLASS:
+ case DECL_ENUM:
+ case DECL_INTERFACE:
+ case DECL_NAMESPACE:
+ case DECL_STRUCT:
+ case DECL_UNION:
+ result = TRUE;
+ break;
- default: result = FALSE; break;
+ default: result = FALSE; break;
+ }
+ }
}
return result;
}
@@ -762,6 +888,7 @@
st->gotArgs = FALSE;
st->gotName = FALSE;
st->haveQualifyingName = FALSE;
+ st->argEndPosition = 0;
st->tokenIndex = 0;
if (st->parent != NULL)
@@ -784,13 +911,37 @@
*/
if (! partial)
st->member.access = st->member.accessDefault;
+
+ /* Init first token */
+ if (!partial)
+ initToken(st->firstToken);
}
+static void reinitStatementWithToken (statementInfo *const st,
+ tokenInfo *token, const boolean partial)
+{
+ tokenInfo *const save = newToken ();
+ /* given token can be part of reinit statementInfo */
+ copyToken (save, token);
+ reinitStatement (st, partial);
+ token = activeToken (st);
+ copyToken (token, save);
+ deleteToken (save);
+ ++st->tokenIndex; /* this is quite save becouse current tokenIndex = 0 */
+}
+
static void initStatement (statementInfo *const st, statementInfo *const parent)
{
st->parent = parent;
initMemberInfo (st);
reinitStatement (st, FALSE);
+ if (parent)
+ {
+ const tokenInfo *const src = activeToken (parent);
+ tokenInfo *const dst = activeToken (st);
+ copyToken (dst, src);
+ st->tokenIndex++;
+ }
}
/*
@@ -843,6 +994,30 @@
return result;
}
+static dKind dTagKind (const tagType type)
+{
+ dKind result = DK_UNDEFINED;
+ switch (type)
+ {
+ case TAG_CLASS: result = DK_CLASS; break;
+ case TAG_ENUM: result = DK_ENUMERATION; break;
+ case TAG_ENUMERATOR: result = DK_ENUMERATOR; break;
+ case TAG_FUNCTION: result = DK_FUNCTION; break;
+ case TAG_INTERFACE: result = DK_INTERFACE; break;
+ case TAG_MEMBER: result = DK_MEMBER; break;
+ case TAG_NAMESPACE: result = DK_NAMESPACE; break;
+ case TAG_PROTOTYPE: result = DK_PROTOTYPE; break;
+ case TAG_STRUCT: result = DK_STRUCT; break;
+ case TAG_TYPEDEF: result = DK_TYPEDEF; break;
+ case TAG_UNION: result = DK_UNION; break;
+ case TAG_VARIABLE: result = DK_VARIABLE; break;
+ case TAG_EXTERN_VAR: result = DK_EXTERN_VARIABLE; break;
+
+ default: Assert ("Bad D tag type" == NULL); break;
+ }
+ return result;
+}
+
static javaKind javaTagKind (const tagType type)
{
javaKind result = JK_UNDEFINED;
@@ -862,6 +1037,30 @@
return result;
}
+static valaKind valaTagKind (const tagType type)
+{
+ valaKind result = VK_UNDEFINED;
+ switch (type)
+ {
+ case TAG_CLASS: result = VAK_CLASS; break;
+ case TAG_ENUM: result = VAK_ENUMERATION; break;
+ case TAG_ENUMERATOR: result = VAK_ENUMERATOR; break;
+ case TAG_SIGNAL: result = VAK_SIGNAL; break;
+ case TAG_FIELD: result = VAK_FIELD ; break;
+ case TAG_INTERFACE: result = VAK_INTERFACE; break;
+ case TAG_LOCAL: result = VAK_LOCAL; break;
+ case TAG_METHOD: result = VAK_METHOD; break;
+ case TAG_NAMESPACE: result = VAK_NAMESPACE; break;
+ case TAG_PROPERTY: result = VAK_PROPERTY; break;
+ case TAG_STRUCT: result = VAK_STRUCT; break;
+
+ default: Assert ("Bad Vala tag type" == NULL); break;
+ }
+ return result;
+}
+
+
+
static veraKind veraTagKind (const tagType type) {
veraKind result = VK_UNDEFINED;
switch (type)
@@ -889,8 +1088,12 @@
const char* result;
if (isLanguage (Lang_csharp))
result = CsharpKinds [csharpTagKind (type)].name;
- else if (isLanguage (Lang_java))
+ else if (isLanguage (Lang_d))
+ result = DKinds [dTagKind (type)].name;
+ if (isLanguage (Lang_java))
result = JavaKinds [javaTagKind (type)].name;
+ else if (isLanguage (Lang_vala))
+ result = ValaKinds [valaTagKind (type)].name;
else if (isLanguage (Lang_vera))
result = VeraKinds [veraTagKind (type)].name;
else
@@ -903,8 +1106,12 @@
int result;
if (isLanguage (Lang_csharp))
result = CsharpKinds [csharpTagKind (type)].letter;
+ else if (isLanguage (Lang_d))
+ result = DKinds [dTagKind (type)].letter;
else if (isLanguage (Lang_java))
result = JavaKinds [javaTagKind (type)].letter;
+ else if (isLanguage (Lang_vala))
+ result = ValaKinds [valaTagKind (type)].letter;
else if (isLanguage (Lang_vera))
result = VeraKinds [veraTagKind (type)].letter;
else
@@ -938,6 +1145,7 @@
case DECL_ENUM: type = TAG_ENUM; break;
case DECL_EVENT: type = TAG_EVENT; break;
case DECL_FUNCTION: type = TAG_FUNCTION; break;
+ case DECL_FUNCTION_TEMPLATE: type = TAG_FUNCTION; break;
case DECL_INTERFACE: type = TAG_INTERFACE; break;
case DECL_NAMESPACE: type = TAG_NAMESPACE; break;
case DECL_PROGRAM: type = TAG_PROGRAM; break;
@@ -953,7 +1161,9 @@
static const char* accessField (const statementInfo *const st)
{
const char* result = NULL;
- if (isLanguage (Lang_cpp) && st->scope == SCOPE_FRIEND)
+
+ if ((isLanguage (Lang_cpp) || isLanguage (Lang_d) || isLanguage (Lang_ferite)) &&
+ st->scope == SCOPE_FRIEND)
result = "friend";
else if (st->member.access != ACCESS_UNDEFINED)
result = accessString (st->member.access);
@@ -964,7 +1174,8 @@
{
if (isLanguage (Lang_c) || isLanguage (Lang_cpp))
vStringCatS (scope, "::");
- else if (isLanguage (Lang_java) || isLanguage (Lang_csharp))
+ else if (isLanguage (Lang_java) || isLanguage (Lang_d) || isLanguage (Lang_ferite) ||
+ isLanguage (Lang_csharp) || isLanguage (Lang_vala))
vStringCatS (scope, ".");
}
@@ -1015,8 +1226,8 @@
vStringValue (st->parentClasses);
}
if (st->implementation != IMP_DEFAULT &&
- (isLanguage (Lang_cpp) || isLanguage (Lang_csharp) ||
- isLanguage (Lang_java)))
+ (isLanguage (Lang_cpp) || isLanguage (Lang_csharp) || isLanguage (Lang_vala) ||
+ isLanguage (Lang_java) || isLanguage (Lang_d) || isLanguage (Lang_ferite)))
{
tag->extensionFields.implementation =
implementationString (st->implementation);
@@ -1146,6 +1357,13 @@
vString *typeRef = vStringNew ();
tagEntryInfo e;
+ /* take only functions which are introduced by "function ..." */
+ if (type == TAG_FUNCTION && isLanguage (Lang_ferite) &&
+ strncmp("function", st->firstToken->name->buffer, 8) != 0)
+ {
+ return;
+ }
+
initTagEntry (&e, vStringValue (token->name));
e.lineNumber = token->lineNumber;
@@ -1201,7 +1419,7 @@
const boolean isFileScope =
(boolean) (st->member.access == ACCESS_PRIVATE ||
(!isMember (st) && st->scope == SCOPE_STATIC));
- if (isLanguage (Lang_java) || isLanguage (Lang_csharp))
+ if (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala))
type = TAG_METHOD;
else if (isLanguage (Lang_vera) && st->declaration == DECL_TASK)
type = TAG_TASK;
@@ -1216,11 +1434,12 @@
{
if (! isType (nameToken, TOKEN_NAME))
;
- else if (isLanguage (Lang_java) || isLanguage (Lang_csharp))
+ else if (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala))
qualifyFunctionTag (st, nameToken);
else if (st->scope == SCOPE_TYPEDEF)
makeTag (nameToken, st, TRUE, TAG_TYPEDEF);
- else if (isValidTypeSpecifier (st->declaration) && ! isLanguage (Lang_csharp))
+ else if (isValidTypeSpecifier (st->declaration) &&
+ ! (isLanguage (Lang_csharp) || isLanguage (Lang_vala)))
makeTag (nameToken, st, TRUE, TAG_PROTOTYPE);
}
@@ -1233,6 +1452,7 @@
const boolean fileScoped = (boolean)
(!(isLanguage (Lang_java) ||
isLanguage (Lang_csharp) ||
+ isLanguage (Lang_vala) ||
isLanguage (Lang_vera)));
if (type != TAG_UNDEFINED)
@@ -1267,6 +1487,8 @@
*/
if (! isType (nameToken, TOKEN_NAME))
;
+ else if (st->declaration == DECL_IGNORE)
+ ;
else if (st->scope == SCOPE_TYPEDEF)
makeTag (nameToken, st, TRUE, TAG_TYPEDEF);
else if (st->declaration == DECL_EVENT)
@@ -1274,18 +1496,22 @@
TAG_EVENT);
else if (st->declaration == DECL_PACKAGE)
makeTag (nameToken, st, FALSE, TAG_PACKAGE);
+ else if (st->declaration == DECL_MODULE) /* handle modules in D as namespaces */
+ makeTag (nameToken, st, FALSE, TAG_NAMESPACE);
else if (isValidTypeSpecifier (st->declaration))
{
if (st->notVariable)
;
else if (isMember (st))
{
- if (isLanguage (Lang_java) || isLanguage (Lang_csharp))
+ if (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala))
makeTag (nameToken, st,
(boolean) (st->member.access == ACCESS_PRIVATE), TAG_FIELD);
else if (st->scope == SCOPE_GLOBAL || st->scope == SCOPE_STATIC)
makeTag (nameToken, st, TRUE, TAG_MEMBER);
}
+ else if (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala))
+ ;
else
{
if (st->scope == SCOPE_EXTERN || ! st->haveQualifyingName)
@@ -1491,7 +1717,7 @@
first = FALSE;
}
c = cppGetc ();
- } while (isident (c) || ((isLanguage (Lang_java) || isLanguage (Lang_csharp)) && (isHighChar (c) || c == '.')));
+ } while (isident (c) || ((isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala)) && (isHighChar (c) || c == '.')));
vStringTerminate (name);
cppUngetc (c); /* unget non-identifier character */
@@ -1517,8 +1743,8 @@
static void readPackageOrNamespace (statementInfo *const st, const declType declaration)
{
st->declaration = declaration;
-
- if (declaration == DECL_NAMESPACE && !isLanguage (Lang_csharp))
+
+ if (declaration == DECL_NAMESPACE && !(isLanguage (Lang_csharp) || isLanguage (Lang_vala)))
{
/* In C++ a namespace is specified one level at a time. */
return;
@@ -1535,6 +1761,20 @@
}
}
+static void readPackage (statementInfo *const st)
+{
+ tokenInfo *const token = activeToken (st);
+ Assert (isType (token, TOKEN_KEYWORD));
+ readPackageName (token, skipToNonWhite ());
+ token->type = TOKEN_NAME;
+ if (isLanguage (Lang_d))
+ st->declaration = DECL_MODULE;
+ else
+ st->declaration = DECL_PACKAGE;
+ st->gotName = TRUE;
+ st->haveQualifyingName = TRUE;
+}
+
static void processName (statementInfo *const st)
{
Assert (isType (activeToken (st), TOKEN_NAME));
@@ -1628,12 +1868,12 @@
{
if (isMember (st))
{
- if (isLanguage (Lang_cpp))
+ if (isLanguage (Lang_cpp) || isLanguage (Lang_d) || isLanguage (Lang_ferite))
{
int c = skipToNonWhite ();
if (c == ':')
- reinitStatement (st, FALSE);
+ reinitStatementWithToken (st, prevToken (st, 1), FALSE);
else
cppUngetc (c);
@@ -1740,10 +1980,13 @@
case KEYWORD_IMPORT: skipStatement (st); break;
case KEYWORD_INT: st->declaration = DECL_BASE; break;
case KEYWORD_INTEGER: st->declaration = DECL_BASE; break;
+ case KEYWORD_BOOLEAN: st->declaration = DECL_BASE; break;
+ case KEYWORD_SIZE_T: st->declaration = DECL_BASE; break;
case KEYWORD_INTERFACE: processInterface (st); break;
case KEYWORD_LOCAL: setAccess (st, ACCESS_LOCAL); break;
case KEYWORD_LONG: st->declaration = DECL_BASE; break;
case KEYWORD_OPERATOR: readOperator (st); break;
+ case KEYWORD_MODULE: readPackage (st); break;
case KEYWORD_PRIVATE: setAccess (st, ACCESS_PRIVATE); break;
case KEYWORD_PROGRAM: st->declaration = DECL_PROGRAM; break;
case KEYWORD_PROTECTED: setAccess (st, ACCESS_PROTECTED); break;
@@ -1762,10 +2005,10 @@
case KEYWORD_VOLATILE: st->declaration = DECL_BASE; break;
case KEYWORD_VIRTUAL: st->implementation = IMP_VIRTUAL; break;
case KEYWORD_WCHAR_T: st->declaration = DECL_BASE; break;
-
+
case KEYWORD_NAMESPACE: readPackageOrNamespace (st, DECL_NAMESPACE); break;
case KEYWORD_PACKAGE: readPackageOrNamespace (st, DECL_PACKAGE); break;
-
+
case KEYWORD_EVENT:
if (isLanguage (Lang_csharp))
st->declaration = DECL_EVENT;
@@ -1776,6 +2019,11 @@
st->scope = SCOPE_TYPEDEF;
break;
+ case KEYWORD_SIGNAL:
+ if (isLanguage (Lang_vala))
+ st->declaration = DECL_SIGNAL;
+ break;
+
case KEYWORD_EXTERN:
if (! isLanguage (Lang_csharp) || !st->gotName)
{
@@ -1786,7 +2034,7 @@
break;
case KEYWORD_STATIC:
- if (! (isLanguage (Lang_java) || isLanguage (Lang_csharp)))
+ if (! (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala)))
{
reinitStatement (st, FALSE);
st->scope = SCOPE_STATIC;
@@ -1927,6 +2175,21 @@
if (isident1 (c))
{
readIdentifier (token, c);
+ if (isLanguage(Lang_d))
+ {
+ switch (token->keyword)
+ {
+ /* template constraint */
+ case KEYWORD_IF:
+ /* contracts */
+ case KEYWORD_IN:
+ case KEYWORD_OUT:
+ case KEYWORD_BODY:
+ token->keyword = KEYWORD_CONST;
+ default:
+ break;
+ }
+ }
switch (token->keyword)
{
case KEYWORD_ATTRIBUTE: skipParens (); break;
@@ -2029,6 +2292,39 @@
setToken (st, TOKEN_NONE);
}
+static void skipValaPostParens (statementInfo *const st)
+{
+ tokenInfo *const token = activeToken (st);
+ int c = skipToNonWhite ();
+
+ while (isident1 (c))
+ {
+ readIdentifier (token, c);
+ if (token->keyword == KEYWORD_ATTRIBUTE)
+ {
+ /* parse contracts */
+ skipParens ();
+ c = skipToNonWhite ();
+ }
+ else if (token->keyword == KEYWORD_THROWS)
+ {
+ do
+ {
+ c = skipToNonWhite ();
+ if (isident1 (c))
+ {
+ readIdentifier (token, c);
+ c = skipToNonWhite ();
+ }
+ } while (c == '.' || c == ',');
+ }
+ else
+ break;
+ }
+ cppUngetc (c);
+ setToken (st, TOKEN_NONE);
+}
+
static void analyzePostParens (statementInfo *const st, parenInfo *const info)
{
const unsigned long inputLineNumber = getInputLineNumber ();
@@ -2039,6 +2335,8 @@
;
else if (isLanguage (Lang_java))
skipJavaThrows (st);
+ else if (isLanguage (Lang_vala))
+ skipValaPostParens(st);
else
{
if (! skipPostArgumentStuff (st, info))
@@ -2087,7 +2385,7 @@
* But watch out for "@interface"!
*/
tokenInfo *const token = activeToken (st);
-
+
int c = skipToNonWhite ();
readIdentifier (token, c);
if (token->keyword == KEYWORD_INTERFACE)
@@ -2320,6 +2618,11 @@
st->gotParenName = TRUE;
if (! (c == '(' && info.nestedArgs))
st->isPointer = info.isPointer;
+ if (isLanguage(Lang_d) && c == '(' && isType (prev, TOKEN_NAME))
+ {
+ st->declaration = DECL_FUNCTION_TEMPLATE;
+ copyToken (st->blockName, prev);
+ }
}
else if (! st->gotArgs && info.isParamList)
{
@@ -2346,7 +2649,9 @@
{
if (isLanguage (Lang_c) || isLanguage (Lang_cpp))
vStringCatS (st->context->name, "::");
- else if (isLanguage (Lang_java) || isLanguage (Lang_csharp))
+ else if (isLanguage (Lang_java) ||
+ isLanguage (Lang_d) || isLanguage (Lang_ferite) ||
+ isLanguage (Lang_csharp) || isLanguage (Lang_vala))
vStringCatS (st->context->name, ".");
}
vStringCat (st->context->name, token->name);
@@ -2380,8 +2685,8 @@
else
{
cppUngetc (c);
- if ((isLanguage (Lang_cpp) || isLanguage (Lang_csharp)) &&
- inheritingDeclaration (st->declaration))
+ if (((isLanguage (Lang_cpp) || isLanguage (Lang_csharp) || isLanguage (Lang_vala)) &&
+ inheritingDeclaration (st->declaration)) || isLanguage (Lang_d))
{
readParents (st, ':');
}
@@ -2489,7 +2794,7 @@
static void parseGeneralToken (statementInfo *const st, const int c)
{
const tokenInfo *const prev = prevToken (st, 1);
-
+
if (isident1 (c) || (isLanguage (Lang_java) && isHighChar (c)))
{
parseIdentifier (st, c);
@@ -2553,12 +2858,19 @@
}
token = activeToken (st);
} while (isType (token, TOKEN_NONE));
+
+ /* We want to know about non-keyword variable types */
+ if (TOKEN_NONE == st->firstToken->type)
+ {
+ if ((TOKEN_NAME == token->type) || isDataTypeKeyword(token))
+ copyToken(st->firstToken, token);
+ }
}
/*
* Scanning support functions
*/
-
+static unsigned int contextual_fake_count = 0;
static statementInfo *CurrentStatement = NULL;
static statementInfo *newStatement (statementInfo *const parent)
@@ -2569,9 +2881,9 @@
for (i = 0 ; i < (unsigned int) NumTokens ; ++i)
st->token [i] = newToken ();
- st->context = newToken ();
- st->blockName = newToken ();
- st->parentClasses = vStringNew ();
+ st->context = newToken ();
+ st->blockName = newToken ();
+ st->parentClasses = vStringNew ();
initStatement (st, parent);
CurrentStatement = st;
@@ -2610,11 +2922,12 @@
if (isType (token, TOKEN_SEMICOLON))
isEnd = TRUE;
else if (isType (token, TOKEN_BRACE_CLOSE))
- /* Java and C# do not require semicolons to end a block. Neither do C++
- * namespaces. All other blocks require a semicolon to terminate them.
+ /* Java, D, C#, Vala do not require semicolons to end a block. Neither do
+ * C++ namespaces. All other blocks require a semicolon to terminate them.
*/
- isEnd = (boolean) (isLanguage (Lang_java) || isLanguage (Lang_csharp) ||
- ! isContextualStatement (st));
+ isEnd = (boolean) (isLanguage (Lang_java) || isLanguage (Lang_d) ||
+ isLanguage (Lang_csharp) || isLanguage (Lang_vala) ||
+ ! isContextualStatement (st));
else
isEnd = FALSE;
@@ -2690,38 +3003,95 @@
case TOKEN_BRACE_OPEN:
if (isType (prev, TOKEN_ARGS))
{
- if (st->haveQualifyingName)
+ if (st->declaration == DECL_FUNCTION_TEMPLATE)
+ qualifyFunctionTag (st, st->blockName);
+ else if (st->haveQualifyingName)
{
if (! isLanguage (Lang_vera))
st->declaration = DECL_FUNCTION;
if (isType (prev2, TOKEN_NAME))
copyToken (st->blockName, prev2);
- qualifyFunctionTag (st, prev2);
+ /* D structure templates */
+ if (isLanguage (Lang_d) &&
+ (st->declaration == DECL_CLASS || st->declaration == DECL_STRUCT ||
+ st->declaration == DECL_INTERFACE || st->declaration == DECL_NAMESPACE))
+ qualifyBlockTag (st, prev2);
+ else
+ {
+ st->declaration = DECL_FUNCTION;
+ qualifyFunctionTag (st, prev2);
+ }
}
}
else if (isContextualStatement (st) ||
st->declaration == DECL_NAMESPACE ||
st->declaration == DECL_PROGRAM)
{
+ tokenInfo *name_token = (tokenInfo *)prev;
+ boolean free_name_token = FALSE;
+
if (isType (prev, TOKEN_NAME))
copyToken (st->blockName, prev);
+
+ if (isType (name_token, TOKEN_NAME))
+ {
+ if (!isLanguage (Lang_vala))
+ copyToken (st->blockName, name_token);
+ else
+ {
+ switch (st->declaration)
+ {
+ case DECL_CLASS:
+ case DECL_ENUM:
+ case DECL_INTERFACE:
+ case DECL_NAMESPACE:
+ case DECL_STRUCT:
+ copyToken (st->blockName, name_token);
+ break;
+
+ /* anything else can be a property */
+ default:
+ /* makeTag (prev, st, FALSE, TAG_PROPERTY); */
+ /* FIXME: temporary hack to get properties shown */
+ makeTag (prev, st, FALSE, TAG_FIELD);
+ break;
+ }
+ }
+ }
else
{
- /* For an anonymous struct or union we use a unique ID
- * a number, so that the members can be found.
- */
- char buf [20]; /* length of "_anon" + digits + null */
- sprintf (buf, "__anon%d", ++AnonymousID);
- vStringCopyS (st->blockName->name, buf);
- st->blockName->type = TOKEN_NAME;
- st->blockName->keyword = KEYWORD_NONE;
+ tokenInfo *contextual_token = (tokenInfo *)prev;
+ if(isContextualKeyword (contextual_token))
+ {
+ char buffer[64];
+
+ name_token = newToken ();
+ free_name_token = TRUE;
+ copyToken (name_token, contextual_token);
+
+ sprintf(buffer, "anon_%s_%d", name_token->name->buffer, contextual_fake_count++);
+ vStringClear(name_token->name);
+ vStringCatS(name_token->name, buffer);
+
+ name_token->type = TOKEN_NAME;
+ name_token->keyword = KEYWORD_NONE;
+
+ advanceToken (st);
+ contextual_token = activeToken (st);
+ copyToken (contextual_token, token);
+ copyToken ((tokenInfo *const)token, name_token);
+ copyToken (st->blockName, name_token);
+ copyToken (st->firstToken, name_token);
+ }
}
- qualifyBlockTag (st, prev);
+ qualifyBlockTag (st, name_token);
+ if (free_name_token)
+ deleteToken (name_token);
}
else if (isLanguage (Lang_csharp))
makeTag (prev, st, FALSE, TAG_PROPERTY);
break;
-
+ case TOKEN_ARRAY:
case TOKEN_SEMICOLON:
case TOKEN_COMMA:
if (insideEnumBody (st))
@@ -2801,6 +3171,8 @@
exception_t exception;
boolean retry;
+ contextual_fake_count = 0;
+
Assert (passCount < 3);
cppInit ((boolean) (passCount > 1), isLanguage (Lang_csharp));
Signature = vStringNew ();
@@ -2854,12 +3226,36 @@
buildKeywordHash (language, 2);
}
+static void initializeDParser (const langType language)
+{
+ Lang_d = language;
+ buildKeywordHash (language, 6);
+}
+
+static void initializeGLSLParser (const langType language)
+{
+ Lang_glsl = language;
+ buildKeywordHash (language, 0); /* C keywords */
+}
+
+static void initializeFeriteParser (const langType language)
+{
+ Lang_ferite = language;
+ buildKeywordHash (language, 1); /* C++ keywords */
+}
+
static void initializeJavaParser (const langType language)
{
Lang_java = language;
buildKeywordHash (language, 3);
}
+static void initializeValaParser (const langType language)
+{
+ Lang_vala = language;
+ buildKeywordHash (language, 5);
+}
+
static void initializeVeraParser (const langType language)
{
Lang_vera = language;
@@ -2882,6 +3278,7 @@
{
static const char *const extensions [] = {
"c++", "cc", "cp", "cpp", "cxx", "h", "h++", "hh", "hp", "hpp", "hxx",
+ "i",
#ifndef CASE_INSENSITIVE_FILENAMES
"C", "H",
#endif
@@ -2920,6 +3317,54 @@
return def;
}
+extern parserDefinition* DParser (void)
+{
+ static const char *const extensions [] = { "d", "di", NULL };
+ parserDefinition* def = parserNew ("D");
+ def->kinds = DKinds;
+ def->kindCount = KIND_COUNT (DKinds);
+ def->extensions = extensions;
+ def->parser2 = findCTags;
+ def->initialize = initializeDParser;
+ return def;
+}
+
+extern parserDefinition* GLSLParser (void)
+{
+ static const char *const extensions [] = { "glsl", "frag", "vert", NULL };
+ parserDefinition* def = parserNew ("GLSL");
+ def->kinds = CKinds;
+ def->kindCount = KIND_COUNT (CKinds);
+ def->extensions = extensions;
+ def->parser2 = findCTags;
+ def->initialize = initializeGLSLParser;
+ return def;
+}
+
+extern parserDefinition* FeriteParser (void)
+{
+ static const char *const extensions [] = { "fe", NULL };
+ parserDefinition* def = parserNew ("Ferite");
+ def->kinds = CKinds;
+ def->kindCount = KIND_COUNT (CKinds);
+ def->extensions = extensions;
+ def->parser2 = findCTags;
+ def->initialize = initializeFeriteParser;
+ return def;
+}
+
+extern parserDefinition* ValaParser (void)
+{
+ static const char *const extensions [] = { "vala", NULL };
+ parserDefinition* def = parserNew ("Vala");
+ def->kinds = ValaKinds;
+ def->kindCount = KIND_COUNT (ValaKinds);
+ def->extensions = extensions;
+ def->parser2 = findCTags;
+ def->initialize = initializeValaParser;
+ return def;
+}
+
extern parserDefinition* VeraParser (void)
{
static const char *const extensions [] = { "vr", "vri", "vrh", NULL };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment