diff -ur ctags-5.5.4/c.c ctags-5.5.4.nem/c.c --- ctags-5.5.4/c.c 2004-02-28 16:37:52.000000000 +0100 +++ ctags-5.5.4.nem/c.c 2005-06-18 19:35:23.005140224 +0200 @@ -76,7 +76,7 @@ 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_PACKED, KEYWORD_PORT, KEYWORD_PACKAGE, KEYWORD_PRIVATE, @@ -90,7 +90,7 @@ KEYWORD_TRY, KEYWORD_TYPEDEF, KEYWORD_TYPENAME, KEYWORD_UINT, KEYWORD_ULONG, KEYWORD_UNION, KEYWORD_UNSIGNED, KEYWORD_USHORT, KEYWORD_USING, - KEYWORD_VIRTUAL, KEYWORD_VOID, KEYWORD_VOLATILE, + KEYWORD_VARIANT, KEYWORD_VIRTUAL, KEYWORD_VOID, KEYWORD_VOLATILE, KEYWORD_WCHAR_T, KEYWORD_WHILE } keywordId; @@ -100,7 +100,7 @@ typedef struct sKeywordDesc { const char *name; keywordId id; - short isValid [5]; /* indicates languages for which kw is valid */ + short isValid [6]; /* indicates languages for which kw is valid */ } keywordDesc; /* Used for reporting the type of object parsed by nextToken (). @@ -257,6 +257,7 @@ static langType Lang_csharp; static langType Lang_java; static langType Lang_vera; +static langType Lang_nemerle; static vString *Signature; static boolean CollectingSignature; @@ -350,115 +351,142 @@ { FALSE, 'x', "externvar", "external variable declarations"} }; +/* Used to index into the NemerleKinds table. */ +typedef enum { + NK_UNDEFINED = -1, + NK_CLASS, NK_DEFINE, NK_ENUMERATOR, NK_EVENT, NK_FIELD, + NK_ENUMERATION, NK_INTERFACE, NK_LOCAL, NK_METHOD, + NK_NAMESPACE, NK_PROPERTY, NK_STRUCT, NK_TYPEDEF +} nemerleKind; + +static kindOption NemerleKinds [] = { + { TRUE, 'c', "class", "classes"}, + { TRUE, 'd', "macro", "macro definitions"}, + { TRUE, 'e', "enumerator", "enumerators (values inside an enumeration)"}, + { TRUE, 'E', "event", "events"}, + { 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', "struct", "structure names"}, + { TRUE, 't', "typedef", "typedefs"}, +}; + 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 } }, - { "double", KEYWORD_DOUBLE, { 1, 1, 1, 1, 0 } }, - { "else", KEYWORD_ELSE, { 1, 1, 0, 1, 0 } }, - { "enum", KEYWORD_ENUM, { 1, 1, 1, 0, 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 } }, - { "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 } } + /* keyword keyword ID | | | | | Nemerle */ + { "__attribute__", KEYWORD_ATTRIBUTE, { 1, 1, 1, 0, 0, 0 } }, + { "abstract", KEYWORD_ABSTRACT, { 0, 0, 1, 1, 0, 1 } }, + { "bad_state", KEYWORD_BAD_STATE, { 0, 0, 0, 0, 1, 0 } }, + { "bad_trans", KEYWORD_BAD_TRANS, { 0, 0, 0, 0, 1, 0 } }, + { "bind", KEYWORD_BIND, { 0, 0, 0, 0, 1, 0 } }, + { "bind_var", KEYWORD_BIND_VAR, { 0, 0, 0, 0, 1, 0 } }, + { "bit", KEYWORD_BIT, { 0, 0, 0, 0, 1, 0 } }, + { "boolean", KEYWORD_BOOLEAN, { 0, 0, 0, 1, 0, 0 } }, + { "byte", KEYWORD_BYTE, { 0, 0, 0, 1, 0, 1 } }, + { "case", KEYWORD_CASE, { 1, 1, 1, 1, 0, 0 } }, + { "catch", KEYWORD_CATCH, { 0, 1, 1, 0, 0, 1 } }, + { "char", KEYWORD_CHAR, { 1, 1, 1, 1, 0, 1 } }, + { "class", KEYWORD_CLASS, { 0, 1, 1, 1, 1, 1 } }, + { "const", KEYWORD_CONST, { 1, 1, 1, 1, 0, 1 } }, + { "constraint", KEYWORD_CONSTRAINT, { 0, 0, 0, 0, 1, 0 } }, + { "coverage_block", KEYWORD_COVERAGE_BLOCK, { 0, 0, 0, 0, 1, 0 } }, + { "coverage_def", KEYWORD_COVERAGE_DEF, { 0, 0, 0, 0, 1, 0 } }, + { "do", KEYWORD_DO, { 1, 1, 1, 1, 0, 1 } }, + { "default", KEYWORD_DEFAULT, { 1, 1, 1, 1, 0, 0 } }, + { "delegate", KEYWORD_DELEGATE, { 0, 0, 1, 0, 0, 1 } }, + { "double", KEYWORD_DOUBLE, { 1, 1, 1, 1, 0, 1 } }, + { "else", KEYWORD_ELSE, { 1, 1, 0, 1, 0, 0 } }, + { "enum", KEYWORD_ENUM, { 1, 1, 1, 0, 1, 1 } }, + { "event", KEYWORD_EVENT, { 0, 0, 1, 0, 1, 1 } }, + { "explicit", KEYWORD_EXPLICIT, { 0, 1, 1, 0, 0, 0 } }, + { "extends", KEYWORD_EXTENDS, { 0, 0, 0, 1, 1, 0 } }, + { "extern", KEYWORD_EXTERN, { 1, 1, 1, 0, 1, 1 } }, + { "final", KEYWORD_FINAL, { 0, 0, 0, 1, 0, 0 } }, + { "float", KEYWORD_FLOAT, { 1, 1, 1, 1, 0, 1 } }, + { "for", KEYWORD_FOR, { 1, 1, 1, 1, 0, 1 } }, + { "friend", KEYWORD_FRIEND, { 0, 1, 0, 0, 0, 0 } }, + { "function", KEYWORD_FUNCTION, { 0, 0, 0, 0, 1, 0 } }, + { "goto", KEYWORD_GOTO, { 1, 1, 1, 1, 0, 0 } }, + { "if", KEYWORD_IF, { 1, 1, 1, 1, 0, 1 } }, + { "implements", KEYWORD_IMPLEMENTS, { 0, 0, 0, 1, 0, 0 } }, + { "import", KEYWORD_IMPORT, { 0, 0, 0, 1, 0, 0 } }, + { "inline", KEYWORD_INLINE, { 0, 1, 0, 0, 0, 0 } }, + { "inout", KEYWORD_INOUT, { 0, 0, 0, 0, 1, 0 } }, + { "input", KEYWORD_INPUT, { 0, 0, 0, 0, 1, 0 } }, + { "int", KEYWORD_INT, { 1, 1, 1, 1, 0, 1 } }, + { "integer", KEYWORD_INTEGER, { 0, 0, 0, 0, 1, 0 } }, + { "interface", KEYWORD_INTERFACE, { 0, 0, 1, 1, 1, 1 } }, + { "internal", KEYWORD_INTERNAL, { 0, 0, 1, 0, 0, 1 } }, + { "local", KEYWORD_LOCAL, { 0, 0, 0, 0, 1, 0 } }, + { "long", KEYWORD_LONG, { 1, 1, 1, 1, 0, 1 } }, + { "m_bad_state", KEYWORD_M_BAD_STATE, { 0, 0, 0, 0, 1, 0 } }, + { "m_bad_trans", KEYWORD_M_BAD_TRANS, { 0, 0, 0, 0, 1, 0 } }, + { "m_state", KEYWORD_M_STATE, { 0, 0, 0, 0, 1, 0 } }, + { "m_trans", KEYWORD_M_TRANS, { 0, 0, 0, 0, 1, 0 } }, + { "module", KEYWORD_MODULE, { 0, 0, 0, 0, 0, 1 } }, + { "mutable", KEYWORD_MUTABLE, { 0, 1, 0, 0, 0, 1 } }, + { "namespace", KEYWORD_NAMESPACE, { 0, 1, 1, 0, 0, 1 } }, + { "native", KEYWORD_NATIVE, { 0, 0, 0, 1, 0, 0 } }, + { "new", KEYWORD_NEW, { 0, 1, 1, 1, 0, 1 } }, + { "newcov", KEYWORD_NEWCOV, { 0, 0, 0, 0, 1, 0 } }, + { "operator", KEYWORD_OPERATOR, { 0, 1, 1, 0, 0, 0 } }, + { "output", KEYWORD_OUTPUT, { 0, 0, 0, 0, 1, 0 } }, + { "overload", KEYWORD_OVERLOAD, { 0, 1, 0, 0, 0, 0 } }, + { "override", KEYWORD_OVERRIDE, { 0, 0, 1, 0, 0, 1 } }, + { "package", KEYWORD_PACKAGE, { 0, 0, 0, 1, 0, 0 } }, + { "packed", KEYWORD_PACKED, { 0, 0, 0, 0, 1, 0 } }, + { "port", KEYWORD_PORT, { 0, 0, 0, 0, 1, 0 } }, + { "private", KEYWORD_PRIVATE, { 0, 1, 1, 1, 0, 1 } }, + { "program", KEYWORD_PROGRAM, { 0, 0, 0, 0, 1, 0 } }, + { "protected", KEYWORD_PROTECTED, { 0, 1, 1, 1, 1, 1 } }, + { "public", KEYWORD_PUBLIC, { 0, 1, 1, 1, 1, 1 } }, + { "register", KEYWORD_REGISTER, { 1, 1, 0, 0, 0, 0 } }, + { "return", KEYWORD_RETURN, { 1, 1, 1, 1, 0, 0 } }, + { "shadow", KEYWORD_SHADOW, { 0, 0, 0, 0, 1, 0 } }, + { "short", KEYWORD_SHORT, { 1, 1, 1, 1, 0, 1 } }, + { "signed", KEYWORD_SIGNED, { 1, 1, 0, 0, 0, 0 } }, + { "state", KEYWORD_STATE, { 0, 0, 0, 0, 1, 0 } }, + { "static", KEYWORD_STATIC, { 1, 1, 1, 1, 1, 1 } }, + { "string", KEYWORD_STRING, { 0, 0, 1, 0, 1, 1 } }, + { "struct", KEYWORD_STRUCT, { 1, 1, 1, 0, 0, 1 } }, + { "switch", KEYWORD_SWITCH, { 1, 1, 1, 1, 0, 0 } }, + { "synchronized", KEYWORD_SYNCHRONIZED, { 0, 0, 0, 1, 0, 0 } }, + { "task", KEYWORD_TASK, { 0, 0, 0, 0, 1, 0 } }, + { "template", KEYWORD_TEMPLATE, { 0, 1, 0, 0, 0, 0 } }, + { "this", KEYWORD_THIS, { 0, 1, 1, 1, 0, 1 } }, + { "throw", KEYWORD_THROW, { 0, 1, 1, 1, 0, 1 } }, + { "throws", KEYWORD_THROWS, { 0, 0, 0, 1, 0, 0 } }, + { "trans", KEYWORD_TRANS, { 0, 0, 0, 0, 1, 0 } }, + { "transition", KEYWORD_TRANSITION, { 0, 0, 0, 0, 1, 0 } }, + { "transient", KEYWORD_TRANSIENT, { 0, 0, 0, 1, 0, 0 } }, + { "try", KEYWORD_TRY, { 0, 1, 1, 0, 0, 1 } }, + { "typedef", KEYWORD_TYPEDEF, { 1, 1, 1, 0, 1, 1 } }, + { "typename", KEYWORD_TYPENAME, { 0, 1, 0, 0, 0, 0 } }, + { "uint", KEYWORD_UINT, { 0, 0, 1, 0, 0, 1 } }, + { "ulong", KEYWORD_ULONG, { 0, 0, 1, 0, 0, 1 } }, + { "union", KEYWORD_UNION, { 1, 1, 0, 0, 0, 0 } }, + { "unsigned", KEYWORD_UNSIGNED, { 1, 1, 1, 0, 0, 1 } }, + { "ushort", KEYWORD_USHORT, { 0, 0, 1, 0, 0, 1 } }, + { "using", KEYWORD_USING, { 0, 1, 1, 0, 0, 1 } }, + { "variant", KEYWORD_VARIANT, { 0, 0, 0, 0, 0, 1 } }, + { "virtual", KEYWORD_VIRTUAL, { 0, 1, 1, 0, 1, 1 } }, + { "void", KEYWORD_VOID, { 1, 1, 1, 1, 1, 1 } }, + { "volatile", KEYWORD_VOLATILE, { 1, 1, 1, 1, 0, 1 } }, + { "wchar_t", KEYWORD_WCHAR_T, { 1, 1, 1, 0, 0, 0 } }, + { "while", KEYWORD_WHILE, { 1, 1, 1, 1, 0, 1 } } }; /* * FUNCTION PROTOTYPES */ static void createTags (const unsigned int nestLevel, statementInfo *const parent); +static void nextToken (statementInfo *const st); /* * FUNCTION DEFINITIONS @@ -664,6 +692,8 @@ case KEYWORD_NAMESPACE: case KEYWORD_STRUCT: case KEYWORD_UNION: + case KEYWORD_MODULE: + case KEYWORD_VARIANT: result = TRUE; break; @@ -828,6 +858,29 @@ return result; } +static nemerleKind nemerleTagKind (const tagType type) +{ + csharpKind result = NK_UNDEFINED; + switch (type) + { + case TAG_CLASS: result = NK_CLASS; break; + case TAG_ENUM: result = NK_ENUMERATION; break; + case TAG_ENUMERATOR: result = NK_ENUMERATOR; break; + case TAG_EVENT: result = NK_EVENT; break; + case TAG_FIELD: result = NK_FIELD ; break; + case TAG_INTERFACE: result = NK_INTERFACE; break; + case TAG_LOCAL: result = NK_LOCAL; break; + case TAG_METHOD: result = NK_METHOD; break; + case TAG_NAMESPACE: result = NK_NAMESPACE; break; + case TAG_PROPERTY: result = NK_PROPERTY; break; + case TAG_STRUCT: result = NK_STRUCT; break; + case TAG_TYPEDEF: result = NK_TYPEDEF; break; + + default: Assert ("Bad Nemerle tag type" == NULL); break; + } + return result; +} + static javaKind javaTagKind (const tagType type) { javaKind result = JK_UNDEFINED; @@ -876,6 +929,8 @@ result = JavaKinds [javaTagKind (type)].name; else if (isLanguage (Lang_vera)) result = VeraKinds [veraTagKind (type)].name; + else if (isLanguage (Lang_nemerle)) + result = NemerleKinds [nemerleTagKind (type)].name; else result = CKinds [cTagKind (type)].name; return result; @@ -890,6 +945,8 @@ result = JavaKinds [javaTagKind (type)].letter; else if (isLanguage (Lang_vera)) result = VeraKinds [veraTagKind (type)].letter; + else if (isLanguage (Lang_nemerle)) + result = NemerleKinds [nemerleTagKind (type)].letter; else result = CKinds [cTagKind (type)].letter; return result; @@ -906,6 +963,8 @@ result = JavaKinds [javaTagKind (type)].enabled; else if (isLanguage (Lang_vera)) result = VeraKinds [veraTagKind (type)].enabled; + else if (isLanguage (Lang_nemerle)) + result = NemerleKinds [nemerleTagKind (type)].enabled; else result = CKinds [cTagKind (type)].enabled; return result; @@ -990,7 +1049,7 @@ } if (st->implementation != IMP_DEFAULT && (isLanguage (Lang_cpp) || isLanguage (Lang_csharp) || - isLanguage (Lang_java))) + isLanguage (Lang_java) || isLanguage (Lang_nemerle))) { tag->extensionFields.implementation = implementationString (st->implementation); @@ -1007,7 +1066,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_csharp) || + isLanguage (Lang_nemerle)) vStringCatS (scope, "."); } @@ -1162,7 +1222,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_nemerle)) type = TAG_METHOD; else if (isLanguage (Lang_vera) && st->declaration == DECL_TASK) type = TAG_TASK; @@ -1177,11 +1237,12 @@ { if (! isType (nameToken, TOKEN_NAME)) ; - else if (isLanguage (Lang_java) || isLanguage (Lang_csharp)) + else if (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_nemerle)) 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_nemerle)) makeTag (nameToken, st, TRUE, TAG_PROTOTYPE); } @@ -1194,6 +1255,7 @@ const boolean fileScoped = (boolean) (!(isLanguage (Lang_java) || isLanguage (Lang_csharp) || + isLanguage (Lang_nemerle) || isLanguage (Lang_vera))); if (type != TAG_UNDEFINED) @@ -1241,7 +1303,7 @@ ; else if (isMember (st)) { - if (isLanguage (Lang_java) || isLanguage (Lang_csharp)) + if (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_nemerle)) makeTag (nameToken, st, (boolean) (st->member.access == ACCESS_PRIVATE), TAG_FIELD); else if (st->scope == SCOPE_GLOBAL || st->scope == SCOPE_STATIC) @@ -1388,9 +1450,15 @@ cppUngetc (c); } +/* Flags set when we have recently seen @ that quotes keywords in + * C# and Nemerle. */ +static boolean seenAntiKeyword = FALSE; + static keywordId analyzeKeyword (const char *const name) { - const keywordId id = (keywordId) lookupKeyword (name, getSourceLanguage ()); + const keywordId id = + seenAntiKeyword ? KEYWORD_NONE + : (keywordId) lookupKeyword (name, getSourceLanguage ()); return id; } @@ -1633,6 +1701,8 @@ vStringPut (parent->name, c); else if (c == '<') skipToMatch ("<>"); + else if (c == '[' && isLanguage (Lang_nemerle)) + skipToMatch ("[]"); else if (isType (token, TOKEN_NAME)) { addParentClass (st, parent); @@ -1663,6 +1733,8 @@ case KEYWORD_BIT: st->declaration = DECL_BASE; break; case KEYWORD_CATCH: skipParens (); skipBraces (); break; case KEYWORD_CHAR: st->declaration = DECL_BASE; break; + case KEYWORD_VARIANT: st->declaration = DECL_CLASS; break; + case KEYWORD_MODULE: st->declaration = DECL_CLASS; break; case KEYWORD_CLASS: st->declaration = DECL_CLASS; break; case KEYWORD_CONST: st->declaration = DECL_BASE; break; case KEYWORD_DOUBLE: st->declaration = DECL_BASE; break; @@ -1703,7 +1775,7 @@ case KEYWORD_VIRTUAL: st->implementation = IMP_VIRTUAL; break; case KEYWORD_EVENT: - if (isLanguage (Lang_csharp)) + if (isLanguage (Lang_csharp) || isLanguage (Lang_nemerle)) st->declaration = DECL_EVENT; break; @@ -1713,7 +1785,8 @@ break; case KEYWORD_EXTERN: - if (! isLanguage (Lang_csharp) || !st->gotName) + if (! (isLanguage (Lang_csharp) || isLanguage (Lang_nemerle)) || + !st->gotName) { reinitStatement (st, FALSE); st->scope = SCOPE_EXTERN; @@ -1722,7 +1795,8 @@ break; case KEYWORD_STATIC: - if (! (isLanguage (Lang_java) || isLanguage (Lang_csharp))) + if (! (isLanguage (Lang_java) || isLanguage (Lang_csharp) || + isLanguage (Lang_nemerle))) { reinitStatement (st, FALSE); st->scope = SCOPE_STATIC; @@ -1879,6 +1953,8 @@ case KEYWORD_CATCH: case KEYWORD_CLASS: + case KEYWORD_MODULE: + case KEYWORD_VARIANT: case KEYWORD_EXPLICIT: case KEYWORD_EXTERN: case KEYWORD_FRIEND: @@ -2206,7 +2282,8 @@ { 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_csharp) || + isLanguage (Lang_nemerle)) vStringCatS (st->context->name, "."); } vStringCat (st->context->name, token->name); @@ -2235,11 +2312,21 @@ else { cppUngetc (c); - if ((isLanguage (Lang_cpp) || isLanguage (Lang_csharp)) && + if ((isLanguage (Lang_cpp) || isLanguage (Lang_csharp) || + isLanguage (Lang_nemerle)) && inheritingDeclaration (st->declaration)) { readParents (st, ':'); } + else if (isLanguage (Lang_nemerle)) + { + const tokenInfo *const prev = prevToken (st, 1); + c = skipToOneOf (";{}"); + if (c == ';' && isType (prev, TOKEN_NAME)) + qualifyVariableTag (st, prev); + cppUngetc (c); + nextToken (st); + } else if (parentDecl (st) == DECL_STRUCT) { c = skipToOneOf (",;"); @@ -2298,7 +2385,11 @@ break; case '[': skipToMatch ("[]"); break; - case '(': skipToMatch ("()"); break; + case '(': + skipToMatch ("()"); + if (isLanguage (Lang_nemerle)) + done = TRUE; + break; case '{': skipToMatch ("{}"); break; case '}': @@ -2413,6 +2504,10 @@ default: parseGeneralToken (st, c); break; } token = activeToken (st); + + seenAntiKeyword = c == '@' && + (isLanguage (Lang_nemerle) || isLanguage (Lang_csharp)); + } while (isType (token, TOKEN_NONE)); } @@ -2475,7 +2570,7 @@ * namespaces. All other blocks require a semicolon to terminate them. */ isEnd = (boolean) (isLanguage (Lang_java) || isLanguage (Lang_csharp) || - ! isContextualStatement (st)); + isLanguage (Lang_nemerle) || ! isContextualStatement (st)); else isEnd = FALSE; @@ -2568,10 +2663,10 @@ copyToken (st->blockName, prev); qualifyBlockTag (st, prev); } - else if (isLanguage (Lang_csharp)) + else if (isLanguage (Lang_csharp) || isLanguage (Lang_nemerle)) makeTag (prev, st, FALSE, TAG_PROPERTY); break; - + case TOKEN_SEMICOLON: case TOKEN_COMMA: if (insideEnumBody (st)) @@ -2645,7 +2740,7 @@ boolean retry; Assert (passCount < 3); - cppInit ((boolean) (passCount > 1)); + cppInit ((boolean) (passCount > 1), (boolean) (isLanguage (Lang_nemerle))); Signature = vStringNew (); exception = (exception_t) setjmp (Exception); @@ -2709,6 +2804,12 @@ buildKeywordHash (language, 4); } +static void initializeNemerleParser (const langType language) +{ + Lang_nemerle = language; + buildKeywordHash (language, 5); +} + extern parserDefinition* CParser (void) { static const char *const extensions [] = { "c", NULL }; @@ -2775,4 +2876,16 @@ return def; } -/* vi:set tabstop=8 shiftwidth=4 noexpandtab: */ +extern parserDefinition* NemerleParser (void) +{ + static const char *const extensions [] = { "n", NULL }; + parserDefinition* def = parserNew ("Nemerle"); + def->kinds = NemerleKinds; + def->kindCount = KIND_COUNT (NemerleKinds); + def->extensions = extensions; + def->parser2 = findCTags; + def->initialize = initializeNemerleParser; + return def; +} + +/* vi:set tabstop=8 shiftwidth=4 sts=4 noexpandtab: */ diff -ur ctags-5.5.4/get.c ctags-5.5.4.nem/get.c --- ctags-5.5.4/get.c 2003-12-14 19:48:38.000000000 +0100 +++ ctags-5.5.4.nem/get.c 2005-06-18 16:14:20.757569496 +0200 @@ -63,6 +63,7 @@ typedef struct sCppState { int ungetch, ungetch2; /* ungotten characters, if any */ boolean resolveRequired; /* must resolve if/else/elif/endif branch */ + boolean allowSingleQuoteId; /* language allows ' in identifiers? */ struct sDirective { enum eState state; /* current directive being processed */ boolean accept; /* is a directive syntatically permitted? */ @@ -83,6 +84,7 @@ static cppState Cpp = { '\0', '\0', /* ungetch characters */ FALSE, /* resolveRequired */ + FALSE, /* allowSingleQuoteId */ { DRCTV_NONE, /* state */ FALSE, /* accept */ @@ -106,13 +108,14 @@ return Cpp.directive.nestLevel; } -extern void cppInit (const boolean state) +extern void cppInit (const boolean state, const boolean allowSingleQuoteId) { BraceFormat = state; Cpp.ungetch = '\0'; Cpp.ungetch2 = '\0'; Cpp.resolveRequired = FALSE; + Cpp.allowSingleQuoteId = allowSingleQuoteId; Cpp.directive.state = DRCTV_NONE; Cpp.directive.accept = TRUE; @@ -501,12 +504,16 @@ { int c; int count = 0, veraBase = '\0'; + boolean seen_backslash = FALSE; while ((c = fileGetc ()) != EOF) { ++count; if (c == BACKSLASH) + { fileGetc (); /* throw away next character, too */ + seen_backslash = TRUE; + } else if (c == SINGLE_QUOTE) break; else if (c == NEWLINE) @@ -514,6 +521,13 @@ fileUngetc (c); break; } + else if (!seen_backslash && count > 1 && Cpp.allowSingleQuoteId) + { + /* Character literals without backslash can be only 1 char long + * and Nemerle allows ' in identifiers. */ + fileUngetc (c); + break; + } else if (count == 1 && strchr ("DHOB", toupper (c)) != NULL) veraBase = c; else if (veraBase != '\0' && ! isalnum (c)) diff -ur ctags-5.5.4/get.h ctags-5.5.4.nem/get.h --- ctags-5.5.4/get.h 2002-09-27 05:07:15.000000000 +0200 +++ ctags-5.5.4.nem/get.h 2005-06-18 16:13:12.530941520 +0200 @@ -37,7 +37,7 @@ */ extern boolean isBraceFormat (void); extern unsigned int getDirectiveNestLevel (void); -extern void cppInit (const boolean state); +extern void cppInit (const boolean state, const boolean allowSingleQuoteId); extern void cppTerminate (void); extern void cppBeginStatement (void); extern void cppEndStatement (void); diff -ur ctags-5.5.4/parsers.h ctags-5.5.4.nem/parsers.h --- ctags-5.5.4/parsers.h 2003-07-18 04:58:22.000000000 +0200 +++ ctags-5.5.4.nem/parsers.h 2005-06-17 21:04:00.759245448 +0200 @@ -33,6 +33,7 @@ LispParser, \ LuaParser, \ MakefileParser, \ + NemerleParser, \ PascalParser, \ PerlParser, \ PhpParser, \