Revision: 1634 http://svn.sourceforge.net/geany/?rev=1634&view=rev Author: eht16 Date: 2007-06-22 10:22:07 -0700 (Fri, 22 Jun 2007)
Log Message: ----------- Use get.c and get.h from CTags SVN. Merged CSharp parser support into from CTags SVN.
Modified Paths: -------------- trunk/tagmanager/c.c trunk/tagmanager/get.c trunk/tagmanager/get.h
Modified: trunk/tagmanager/c.c =================================================================== --- trunk/tagmanager/c.c 2007-06-20 12:42:06 UTC (rev 1633) +++ trunk/tagmanager/c.c 2007-06-22 17:22:07 UTC (rev 1634) @@ -57,39 +57,48 @@ /* Used to specify type of keyword. */ typedef enum eKeywordId { - KEYWORD_NONE, - KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT, - KEYWORD_BOOLEAN, KEYWORD_BYTE, - KEYWORD_CATCH, KEYWORD_CHAR, KEYWORD_CLASS, KEYWORD_CONST, - KEYWORD_DOUBLE, - KEYWORD_ENUM, KEYWORD_EXPLICIT, KEYWORD_EXTERN, KEYWORD_EXTENDS, - KEYWORD_FINAL, KEYWORD_FLOAT, KEYWORD_FRIEND, - KEYWORD_IMPLEMENTS, KEYWORD_IMPORT, KEYWORD_INLINE, KEYWORD_INT, - KEYWORD_INTERFACE, - KEYWORD_LONG, - KEYWORD_MODULE, - KEYWORD_MUTABLE, - KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NATIVE, - KEYWORD_OPERATOR, KEYWORD_OVERLOAD, - KEYWORD_PACKAGE, KEYWORD_PRIVATE, KEYWORD_PROTECTED, KEYWORD_PUBLIC, - KEYWORD_REGISTER, - KEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STRUCT, - KEYWORD_SYNCHRONIZED, - KEYWORD_TEMPLATE, KEYWORD_THROW, KEYWORD_THROWS, KEYWORD_TRANSIENT, - KEYWORD_TRY, KEYWORD_TYPEDEF, KEYWORD_TYPENAME, - KEYWORD_UNION, KEYWORD_UNSIGNED, KEYWORD_USES, KEYWORD_USING, - KEYWORD_VIRTUAL, KEYWORD_VOID, KEYWORD_VOLATILE, - KEYWORD_WCHAR_T, KEYWORD_AUTO, KEYWORD_RESTRICT, KEYWORD_SIZE_T, - KEYWORD_BOOL + KEYWORD_NONE, + KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT, + KEYWORD_BOOLEAN, KEYWORD_BYTE, KEYWORD_BAD_STATE, KEYWORD_BAD_TRANS, + KEYWORD_BIND, KEYWORD_BIND_VAR, KEYWORD_BIT, + 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_FRIEND, KEYWORD_FUNCTION, + KEYWORD_GOTO, + KEYWORD_IF, KEYWORD_IMPLEMENTS, KEYWORD_IMPORT, 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_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, + KEYWORD_PROGRAM, KEYWORD_PROTECTED, KEYWORD_PUBLIC, + KEYWORD_REGISTER, KEYWORD_RETURN, + KEYWORD_SHADOW, KEYWORD_STATE, + KEYWORD_SHORT, 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, + 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_WCHAR_T, KEYWORD_WHILE } keywordId;
/* Used to determine whether keyword is valid for the current language and * what its ID is. */ typedef struct sKeywordDesc { - const char *name; - keywordId id; - short isValid [3]; /* indicates languages for which kw is valid */ + const char *name; + keywordId id; + short isValid [5]; /* indicates languages for which kw is valid */ } keywordDesc;
/* Used for reporting the type of object parsed by nextToken (). @@ -127,6 +136,7 @@ DECL_BASE, /* base type (default) */ DECL_CLASS, DECL_ENUM, + DECL_EVENT, DECL_FUNCTION, DECL_IGNORE, /* non-taggable "declaration" */ DECL_INTERFACE, @@ -218,6 +228,9 @@ TAG_VARIABLE, /* variable definition */ TAG_EXTERN_VAR, /* external variable declaration */ TAG_MACRO, /* #define s */ + TAG_EVENT, /* event */ + TAG_LOCAL, /* local variable definition */ + TAG_PROPERTY, /* property name */ TAG_COUNT /* must be last */ } tagType;
@@ -239,6 +252,7 @@
static langType Lang_c; static langType Lang_cpp; +static langType Lang_csharp; static langType Lang_java; static langType Lang_d; static langType Lang_ferite; @@ -283,70 +297,138 @@ { TRUE, 'p', "package", "packages"}, };
+typedef enum { + CSK_UNDEFINED = -1, + CSK_CLASS, CSK_DEFINE, CSK_ENUMERATOR, CSK_EVENT, CSK_FIELD, + CSK_ENUMERATION, CSK_INTERFACE, CSK_LOCAL, CSK_METHOD, + CSK_NAMESPACE, CSK_PROPERTY, CSK_STRUCT, CSK_TYPEDEF +} csharpKind; + +static kindOption CsharpKinds [] = { + { 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 | Java */ - /* keyword keyword ID \ | / */ - { "__attribute__", KEYWORD_ATTRIBUTE, { 1, 1, 0 } }, - { "abstract", KEYWORD_ABSTRACT, { 0, 0, 1 } }, - { "boolean", KEYWORD_BOOLEAN, { 0, 0, 1 } }, - { "byte", KEYWORD_BYTE, { 0, 0, 1 } }, - { "catch", KEYWORD_CATCH, { 0, 1, 0 } }, - { "char", KEYWORD_CHAR, { 1, 1, 1 } }, - { "class", KEYWORD_CLASS, { 0, 1, 1 } }, - { "const", KEYWORD_CONST, { 1, 1, 1 } }, - { "double", KEYWORD_DOUBLE, { 1, 1, 1 } }, - { "enum", KEYWORD_ENUM, { 1, 1, 0 } }, - { "explicit", KEYWORD_EXPLICIT, { 0, 1, 0 } }, - { "extends", KEYWORD_EXTENDS, { 0, 0, 1 } }, - { "extern", KEYWORD_EXTERN, { 1, 1, 0 } }, - { "final", KEYWORD_FINAL, { 0, 0, 1 } }, - { "float", KEYWORD_FLOAT, { 1, 1, 1 } }, - { "friend", KEYWORD_FRIEND, { 0, 1, 0 } }, - { "implements", KEYWORD_IMPLEMENTS, { 0, 0, 1 } }, - { "import", KEYWORD_IMPORT, { 0, 0, 1 } }, - { "inline", KEYWORD_INLINE, { 0, 1, 0 } }, - { "int", KEYWORD_INT, { 1, 1, 1 } }, - { "interface", KEYWORD_INTERFACE, { 0, 0, 1 } }, - { "long", KEYWORD_LONG, { 1, 1, 1 } }, - { "module", KEYWORD_MODULE, { 0, 1, 0 } }, - { "mutable", KEYWORD_MUTABLE, { 0, 1, 0 } }, - { "namespace", KEYWORD_NAMESPACE, { 0, 1, 0 } }, - { "native", KEYWORD_NATIVE, { 0, 0, 1 } }, - { "new", KEYWORD_NEW, { 0, 1, 1 } }, - { "operator", KEYWORD_OPERATOR, { 0, 1, 0 } }, - { "overload", KEYWORD_OVERLOAD, { 0, 1, 0 } }, - { "package", KEYWORD_PACKAGE, { 0, 0, 1 } }, - { "private", KEYWORD_PRIVATE, { 0, 1, 1 } }, - { "protected", KEYWORD_PROTECTED, { 0, 1, 1 } }, - { "public", KEYWORD_PUBLIC, { 0, 1, 1 } }, - { "register", KEYWORD_REGISTER, { 1, 1, 0 } }, - { "short", KEYWORD_SHORT, { 1, 1, 1 } }, - { "signed", KEYWORD_SIGNED, { 1, 1, 0 } }, - { "static", KEYWORD_STATIC, { 1, 1, 1 } }, - { "struct", KEYWORD_STRUCT, { 1, 1, 0 } }, - { "synchronized", KEYWORD_SYNCHRONIZED, { 0, 0, 1 } }, - { "template", KEYWORD_TEMPLATE, { 0, 1, 0 } }, - { "throw", KEYWORD_THROW, { 0, 1, 1 } }, - { "throws", KEYWORD_THROWS, { 0, 0, 1 } }, - { "transient", KEYWORD_TRANSIENT, { 0, 0, 1 } }, - { "try", KEYWORD_TRY, { 0, 1, 0 } }, - { "typedef", KEYWORD_TYPEDEF, { 1, 1, 0 } }, - { "typename", KEYWORD_TYPENAME, { 0, 1, 0 } }, - { "union", KEYWORD_UNION, { 1, 1, 0 } }, - { "unsigned", KEYWORD_UNSIGNED, { 1, 1, 0 } }, - { "uses", KEYWORD_USES, { 0, 1, 0 } }, - { "using", KEYWORD_USING, { 0, 1, 0 } }, - { "virtual", KEYWORD_VIRTUAL, { 0, 1, 0 } }, - { "void", KEYWORD_VOID, { 1, 1, 1 } }, - { "volatile", KEYWORD_VOLATILE, { 1, 1, 1 } }, - { "wchar_t", KEYWORD_WCHAR_T, { 1, 1, 0 } }, - { "auto", KEYWORD_AUTO, { 1, 1, 0 } }, - { "restrict", KEYWORD_RESTRICT, { 1, 0, 0 } }, - { "size_t", KEYWORD_SIZE_T, { 1, 1, 0 } }, - { "bool", KEYWORD_BOOL, { 0, 1, 0 } } + /* 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, 0, 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 } }, + { "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 } }, + { "module", KEYWORD_MODULE, { 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 } }, + { "size_t", KEYWORD_SIZE_T, { 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 } } };
+ /* * FUNCTION PROTOTYPES */ @@ -630,7 +712,6 @@ case KEYWORD_VOID: case KEYWORD_WCHAR_T: case KEYWORD_SIZE_T: - case KEYWORD_BOOL: return TRUE; default: return FALSE; } @@ -645,8 +726,6 @@ case KEYWORD_EXTERN: case KEYWORD_REGISTER: case KEYWORD_STATIC: - case KEYWORD_AUTO: - case KEYWORD_RESTRICT: case KEYWORD_VIRTUAL: case KEYWORD_SIGNED: case KEYWORD_UNSIGNED: @@ -826,6 +905,29 @@ return result; }
+static csharpKind csharpTagKind (const tagType type) +{ + csharpKind result = CSK_UNDEFINED; + switch (type) + { + case TAG_CLASS: result = CSK_CLASS; break; + case TAG_ENUM: result = CSK_ENUMERATION; break; + case TAG_ENUMERATOR: result = CSK_ENUMERATOR; break; + case TAG_EVENT: result = CSK_EVENT; break; + case TAG_FIELD: result = CSK_FIELD ; break; + case TAG_INTERFACE: result = CSK_INTERFACE; break; + case TAG_LOCAL: result = CSK_LOCAL; break; + case TAG_METHOD: result = CSK_METHOD; break; + case TAG_NAMESPACE: result = CSK_NAMESPACE; break; + case TAG_PROPERTY: result = CSK_PROPERTY; break; + case TAG_STRUCT: result = CSK_STRUCT; break; + case TAG_TYPEDEF: result = CSK_TYPEDEF; break; + + default: Assert ("Bad C# tag type" == NULL); break; + } + return result; +} + static javaKind javaTagKind (const tagType type) { javaKind result = JK_UNDEFINED; @@ -846,9 +948,11 @@ { const char* result; if (isLanguage (Lang_java)) - result = JavaKinds [javaTagKind (type)].name; + result = JavaKinds [javaTagKind (type)].name; + else if (isLanguage (Lang_csharp)) + result = CsharpKinds [csharpTagKind (type)].name; else - result = CKinds [cTagKind (type)].name; + result = CKinds [cTagKind (type)].name; return result; }
@@ -856,9 +960,11 @@ { int result; if (isLanguage (Lang_java)) - result = JavaKinds [javaTagKind (type)].letter; + result = JavaKinds [javaTagKind (type)].letter; + if (isLanguage (Lang_csharp)) + result = CsharpKinds [csharpTagKind (type)].letter; else - result = CKinds [cTagKind (type)].letter; + result = CKinds [cTagKind (type)].letter; return result; }
@@ -929,42 +1035,34 @@ case TAG_STRUCT: case TAG_TYPEDEF: case TAG_UNION: - if (isMember (st) && - ! (type == TAG_ENUMERATOR && vStringLength (scope) == 0)) - { - if (isType (st->context, TOKEN_NAME)) - tag->extensionFields.scope [0] = tagName (TAG_CLASS); - else - tag->extensionFields.scope [0] = - tagName (declToTagType (parentDecl (st))); - tag->extensionFields.scope [1] = vStringValue (scope); - } - if ((type == TAG_CLASS || type == TAG_INTERFACE || - type == TAG_STRUCT) && vStringLength (st->parentClasses) > 0) - { + if (vStringLength (scope) > 0 && + (isMember (st) || st->parent->declaration == DECL_NAMESPACE)) + { + if (isType (st->context, TOKEN_NAME)) + tag->extensionFields.scope [0] = tagName (TAG_CLASS); + else + tag->extensionFields.scope [0] = + tagName (declToTagType (parentDecl (st))); + tag->extensionFields.scope [1] = vStringValue (scope); + } + if ((type == TAG_CLASS || type == TAG_INTERFACE || + type == TAG_STRUCT) && vStringLength (st->parentClasses) > 0) + {
- tag->extensionFields.inheritance = - vStringValue (st->parentClasses); - } - if (st->implementation != IMP_DEFAULT && - (isLanguage (Lang_cpp) || isLanguage (Lang_java) || - isLanguage (Lang_d) || isLanguage (Lang_ferite))) - { - tag->extensionFields.implementation = - implementationString (st->implementation); - } - if (isMember (st)) - { - tag->extensionFields.access = accessField (st); - } - if ((TRUE == st->gotArgs) && (TRUE == Option.extensionFields.argList) && - ((TAG_FUNCTION == type) || (TAG_METHOD == type) || (TAG_PROTOTYPE == type))) { - - if (1) { - tag->extensionFields.arglist = getArglistFromPos( - tag->filePosition, tag->name); + tag->extensionFields.inheritance = + vStringValue (st->parentClasses); } - } + if (st->implementation != IMP_DEFAULT && + (isLanguage (Lang_cpp) || isLanguage (Lang_csharp) || + isLanguage (Lang_java))) + { + tag->extensionFields.implementation = + implementationString (st->implementation); + } + if (isMember (st)) + { + tag->extensionFields.access = accessField (st); + } break; }
@@ -984,7 +1082,7 @@ if (isLanguage (Lang_c) || isLanguage (Lang_cpp)) vStringCatS (scope, "::"); else if (isLanguage (Lang_java) || - isLanguage (Lang_d) || isLanguage (Lang_ferite)) + isLanguage (Lang_d) || isLanguage (Lang_ferite) || isLanguage (Lang_csharp)) vStringCatS (scope, "."); }
@@ -1152,7 +1250,8 @@ { if (isType (nameToken, TOKEN_NAME)) { - const tagType type = isLanguage (Lang_java) ? TAG_METHOD : TAG_FUNCTION; + const tagType type = (isLanguage (Lang_java) || isLanguage (Lang_csharp)) + ? TAG_METHOD : TAG_FUNCTION; const boolean isFileScope = (boolean) (st->member.access == ACCESS_PRIVATE || (!isMember (st) && st->scope == SCOPE_STATIC)); @@ -1166,12 +1265,12 @@ { if (! isType (nameToken, TOKEN_NAME)) ; - else if (isLanguage (Lang_java)) - qualifyFunctionTag (st, nameToken); + else if (isLanguage (Lang_java) || isLanguage (Lang_csharp)) + qualifyFunctionTag (st, nameToken); else if (st->scope == SCOPE_TYPEDEF) - makeTag (nameToken, st, TRUE, TAG_TYPEDEF); - else if (isValidTypeSpecifier (st->declaration)) - makeTag (nameToken, st, TRUE, TAG_PROTOTYPE); + makeTag (nameToken, st, TRUE, TAG_TYPEDEF); + else if (isValidTypeSpecifier (st->declaration) && ! isLanguage (Lang_csharp)) + makeTag (nameToken, st, TRUE, TAG_PROTOTYPE); }
static void qualifyCompoundTag (const statementInfo *const st, @@ -1182,7 +1281,7 @@ const tagType type = declToTagType (st->declaration);
if (type != TAG_UNDEFINED) - makeTag (nameToken, st, (boolean) (! isLanguage (Lang_java)), type); + makeTag (nameToken, st, (boolean) (! isLanguage (Lang_java) && ! isLanguage (Lang_csharp)), type); } }
@@ -1224,7 +1323,7 @@ { if (isMember (st)) { - if (isLanguage (Lang_java)) + if (isLanguage (Lang_java) || isLanguage (Lang_csharp)) makeTag (nameToken, st, (boolean) (st->member.access == ACCESS_PRIVATE), TAG_FIELD); @@ -1246,6 +1345,15 @@ * Parsing functions */
+static int skipToOneOf (const char *const chars) +{ + int c; + do + c = cppGetc (); + while (c != EOF && c != '\0' && strchr (chars, c) == NULL); + return c; +} + /* Skip to the next non-white character. */ static int skipToNonWhite (void) @@ -1417,6 +1525,27 @@ cppUngetc (c); /* unget non-package character */ }
+static void readPackageOrNamespace (statementInfo *const st, const declType declaration) +{ + st->declaration = declaration; + + if (declaration == DECL_NAMESPACE && !isLanguage (Lang_csharp)) + { + /* In C++ a namespace is specified one level at a time. */ + return; + } + else + { + /* In C#, a namespace can also be specified like a Java package name. */ + tokenInfo *const token = activeToken (st); + Assert (isType (token, TOKEN_KEYWORD)); + readPackageName (token, skipToNonWhite ()); + token->type = TOKEN_NAME; + st->gotName = TRUE; + st->haveQualifyingName = TRUE; + } +} + static void readPackage (statementInfo *const st) { tokenInfo *const token = activeToken (st); @@ -1611,8 +1740,6 @@ case KEYWORD_CHAR: st->declaration = DECL_BASE; break; case KEYWORD_CLASS: st->declaration = DECL_CLASS; break; case KEYWORD_CONST: st->declaration = DECL_BASE; break; - case KEYWORD_AUTO: st->declaration = DECL_BASE; break; - case KEYWORD_RESTRICT: st->declaration = DECL_BASE; break; case KEYWORD_DOUBLE: st->declaration = DECL_BASE; break; case KEYWORD_ENUM: st->declaration = DECL_ENUM; break; case KEYWORD_EXTENDS: readParents (st, '.'); @@ -1623,15 +1750,13 @@ setToken (st, TOKEN_NONE); break; case KEYWORD_IMPORT: st->declaration = DECL_IGNORE; break; case KEYWORD_INT: st->declaration = DECL_BASE; break; - case KEYWORD_BOOL: st->declaration = DECL_BASE; break; + case KEYWORD_BOOLEAN: st->declaration = DECL_BASE; break; case KEYWORD_WCHAR_T: st->declaration = DECL_BASE; break; case KEYWORD_SIZE_T: st->declaration = DECL_BASE; break; case KEYWORD_INTERFACE: st->declaration = DECL_INTERFACE; break; case KEYWORD_LONG: st->declaration = DECL_BASE; break; - case KEYWORD_NAMESPACE: st->declaration = DECL_NAMESPACE; break; case KEYWORD_OPERATOR: readOperator (st); break; case KEYWORD_MODULE: readPackage (st); break; - case KEYWORD_PACKAGE: readPackage (st); break; case KEYWORD_PRIVATE: setAccess (st, ACCESS_PRIVATE); break; case KEYWORD_PROTECTED: setAccess (st, ACCESS_PROTECTED); break; case KEYWORD_PUBLIC: setAccess (st, ACCESS_PUBLIC); break; @@ -1647,16 +1772,30 @@ case KEYWORD_VOLATILE: st->declaration = DECL_BASE; break; case KEYWORD_VIRTUAL: st->implementation = IMP_VIRTUAL; 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; + break; + case KEYWORD_EXTERN: - st->scope = SCOPE_EXTERN; - st->declaration = DECL_BASE; - break; + if (! isLanguage (Lang_csharp) || !st->gotName) + { + //reinitStatement (st, FALSE); + st->scope = SCOPE_EXTERN; + st->declaration = DECL_BASE; + } + break;
case KEYWORD_STATIC: - if (! isLanguage (Lang_java)) - st->scope = SCOPE_STATIC; - st->declaration = DECL_BASE; - break; + if (! isLanguage (Lang_java) && ! isLanguage (Lang_csharp)) + { + //reinitStatement (st, FALSE); + st->scope = SCOPE_STATIC; + st->declaration = DECL_BASE; + } + break; } }
@@ -2097,7 +2236,7 @@ if (isLanguage (Lang_c) || isLanguage (Lang_cpp)) vStringCatS (st->context->name, "::"); else if (isLanguage (Lang_java) || - isLanguage (Lang_d) || isLanguage (Lang_ferite)) + isLanguage (Lang_d) || isLanguage (Lang_ferite) || isLanguage (Lang_csharp)) vStringCatS (st->context->name, "."); } vStringCat (st->context->name, token->name); @@ -2105,25 +2244,52 @@ } }
+static boolean inheritingDeclaration (declType decl) +{ + return (boolean) ( + decl == DECL_CLASS || + decl == DECL_STRUCT || + decl == DECL_INTERFACE); +} + static void processColon (statementInfo *const st) { - const int c = skipToNonWhite (); - const boolean doubleColon = (boolean) (c == ':'); + int c = skipToNonWhite (); + const boolean doubleColon = (boolean) (c == ':');
- if (doubleColon) - { - setToken (st, TOKEN_DOUBLE_COLON); - st->haveQualifyingName = FALSE; - } - else - { - cppUngetc (c); - if ((isLanguage (Lang_cpp) || isLanguage (Lang_d) || isLanguage (Lang_ferite)) && ( - st->declaration == DECL_CLASS || st->declaration == DECL_STRUCT)) + if (doubleColon) { - readParents (st, ':'); + setToken (st, TOKEN_DOUBLE_COLON); + st->haveQualifyingName = FALSE; } - } + else + { + cppUngetc (c); + if ((isLanguage (Lang_cpp) || isLanguage (Lang_csharp)) && + inheritingDeclaration (st->declaration)) + { + readParents (st, ':'); + } + else if (parentDecl (st) == DECL_STRUCT) + { + c = skipToOneOf (",;"); + if (c == ',') + setToken (st, TOKEN_COMMA); + else if (c == ';') + setToken (st, TOKEN_SEMICOLON); + } + else + { + const tokenInfo *const prev = prevToken (st, 1); + const tokenInfo *const prev2 = prevToken (st, 2); + if (prev->keyword == KEYWORD_DEFAULT || + prev2->keyword == KEYWORD_CASE || + st->parent != NULL) + { + reinitStatement (st, FALSE); + } + } + } }
/* Skips over any initializing value which may follow an '=' character in a @@ -2314,7 +2480,7 @@ /* Java, D, C# 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_d) || + isEnd = (boolean) (isLanguage (Lang_java) || isLanguage (Lang_d) || isLanguage (Lang_csharp) || ! isContextualStatement (st)); else isEnd = FALSE; @@ -2426,6 +2592,8 @@ { copyToken (st->blockName, name_token); } + else if (isLanguage (Lang_csharp)) + makeTag (prev, st, FALSE, TAG_PROPERTY); else { tokenInfo *contextual_token = (tokenInfo *)prev; @@ -2538,7 +2706,7 @@ boolean retry;
Assert (passCount < 3); - cppInit ((boolean) (passCount > 1)); + cppInit ((boolean) (passCount > 1), isLanguage (Lang_csharp));
exception = (exception_t) setjmp (Exception); retry = FALSE; @@ -2591,7 +2759,7 @@ { contextual_fake_count = 0; Lang_java = language; - buildKeywordHash (language, 2); + buildKeywordHash (language, 3); }
static void initializeDParser (const langType language) @@ -2608,6 +2776,13 @@ buildKeywordHash (language, 1); }
+static void initializeCsharpParser (const langType language) +{ + contextual_fake_count = 0; + Lang_csharp = language; + buildKeywordHash (language, 2); +} + extern parserDefinition* CParser (void) { static const char *const extensions [] = { "c", "pc", "sc", NULL }; @@ -2675,4 +2850,15 @@ return def; }
+extern parserDefinition* CsharpParser (void) +{ + static const char *const extensions [] = { "cs", NULL }; + parserDefinition* def = parserNew ("C#"); + def->kinds = CsharpKinds; + def->kindCount = KIND_COUNT (CsharpKinds); + def->extensions = extensions; + def->parser2 = findCTags; + def->initialize = initializeCsharpParser; + return def; +} /* vi:set tabstop=8 shiftwidth=4: */
Modified: trunk/tagmanager/get.c =================================================================== --- trunk/tagmanager/get.c 2007-06-20 12:42:06 UTC (rev 1633) +++ trunk/tagmanager/get.c 2007-06-22 17:22:07 UTC (rev 1634) @@ -1,6 +1,7 @@ /* +* $Id$ * -* Copyright (c) 1996-2001, Darren Hiebert +* Copyright (c) 1996-2002, Darren Hiebert * * This source code is released for free distribution under the terms of the * GNU General Public License. @@ -12,14 +13,12 @@ /* * INCLUDE FILES */ -#include "general.h" /* must always come first */ -#include <glib.h> +#include "general.h" /* must always come first */
#include <string.h>
#include "entry.h" #include "get.h" -#include "main.h" #include "options.h" #include "read.h" #include "vstring.h" @@ -27,8 +26,8 @@ /* * MACROS */ -#define stringMatch(s1,s2) (strcmp (s1,s2) == 0) -#define isspacetab(c) ((c) == ' ' || (c) == '\t') +#define stringMatch(s1,s2) (strcmp (s1,s2) == 0) +#define isspacetab(c) ((c) == SPACE || (c) == TAB)
/* * DATA DECLARATIONS @@ -36,37 +35,41 @@ typedef enum { COMMENT_NONE, COMMENT_C, COMMENT_CPLUS } Comment;
enum eCppLimits { - MaxCppNestingLevel = 20, - MaxDirectiveName = 10 + MaxCppNestingLevel = 20, + MaxDirectiveName = 10 };
/* Defines the one nesting level of a preprocessor conditional. */ typedef struct sConditionalInfo { - boolean ignoreAllBranches; /* ignoring parent conditional branch */ - boolean singleBranch; /* choose only one branch */ - boolean branchChosen; /* branch already selected */ - boolean ignoring; /* current ignore state */ + boolean ignoreAllBranches; /* ignoring parent conditional branch */ + boolean singleBranch; /* choose only one branch */ + boolean branchChosen; /* branch already selected */ + boolean ignoring; /* current ignore state */ } conditionalInfo;
+enum eState { + DRCTV_NONE, /* no known directive - ignore to end of line */ + DRCTV_DEFINE, /* "#define" encountered */ + DRCTV_HASH, /* initial '#' read; determine directive */ + DRCTV_IF, /* "#if" or "#ifdef" encountered */ + DRCTV_PRAGMA, /* #pragma encountered */ + DRCTV_UNDEF /* "#undef" encountered */ +}; + /* Defines the current state of the pre-processor. */ typedef struct sCppState { - int ungetch, ungetch2; /* ungotten characters, if any */ - boolean resolveRequired; /* must resolve if/else/elif/endif branch */ - struct sDirective { - enum eState { - DRCTV_NONE, /* no known directive - ignore to end of line */ - DRCTV_DEFINE, /* "#define" encountered */ - DRCTV_HASH, /* initial '#' read; determine directive */ - DRCTV_IF, /* "#if" or "#ifdef" encountered */ - DRCTV_UNDEF /* "#undef" encountered */ - } state; - boolean accept; /* is a directive syntatically permitted? */ - vString * name; /* macro name */ - unsigned int nestLevel; /* level 0 is not used */ - conditionalInfo ifdef [MaxCppNestingLevel]; - } directive; + int ungetch, ungetch2; /* ungotten characters, if any */ + boolean resolveRequired; /* must resolve if/else/elif/endif branch */ + boolean hasAtLiteralStrings; /* supports @"c:" strings */ + struct sDirective { + enum eState state; /* current directive being processed */ + boolean accept; /* is a directive syntactically permitted? */ + vString * name; /* macro name */ + unsigned int nestLevel; /* level 0 is not used */ + conditionalInfo ifdef [MaxCppNestingLevel]; + } directive; } cppState;
/* @@ -78,15 +81,16 @@ static boolean BraceFormat = FALSE;
static cppState Cpp = { - '\0', '\0', /* ungetch characters */ - FALSE, /* resolveRequired */ - { - DRCTV_NONE, /* state */ - FALSE, /* accept */ - NULL, /* tag name */ - 0, /* nestLevel */ - { {FALSE,FALSE,FALSE,FALSE} } /* ifdef array */ - } /* directive */ + '\0', '\0', /* ungetch characters */ + FALSE, /* resolveRequired */ + FALSE, /* hasAtLiteralStrings */ + { + DRCTV_NONE, /* state */ + FALSE, /* accept */ + NULL, /* tag name */ + 0, /* nestLevel */ + { {FALSE,FALSE,FALSE,FALSE} } /* ifdef array */ + } /* directive */ };
/* @@ -95,49 +99,55 @@
extern boolean isBraceFormat (void) { - return BraceFormat; + return BraceFormat; }
extern unsigned int getDirectiveNestLevel (void) { - return Cpp.directive.nestLevel; + return Cpp.directive.nestLevel; }
-extern void cppInit (const boolean state) +extern void cppInit (const boolean state, const boolean hasAtLiteralStrings) { - BraceFormat = state; + BraceFormat = state;
- Cpp.ungetch = '\0'; - Cpp.ungetch2 = '\0'; - Cpp.resolveRequired = FALSE; + Cpp.ungetch = '\0'; + Cpp.ungetch2 = '\0'; + Cpp.resolveRequired = FALSE; + Cpp.hasAtLiteralStrings = hasAtLiteralStrings;
- Cpp.directive.state = DRCTV_NONE; - Cpp.directive.accept = TRUE; - Cpp.directive.nestLevel = 0; + Cpp.directive.state = DRCTV_NONE; + Cpp.directive.accept = TRUE; + Cpp.directive.nestLevel = 0;
- if (Cpp.directive.name == NULL) - Cpp.directive.name = vStringNew (); - else - vStringClear (Cpp.directive.name); + Cpp.directive.ifdef [0].ignoreAllBranches = FALSE; + Cpp.directive.ifdef [0].singleBranch = FALSE; + Cpp.directive.ifdef [0].branchChosen = FALSE; + Cpp.directive.ifdef [0].ignoring = FALSE; + + if (Cpp.directive.name == NULL) + Cpp.directive.name = vStringNew (); + else + vStringClear (Cpp.directive.name); }
extern void cppTerminate (void) { - if (Cpp.directive.name != NULL) - { - vStringDelete (Cpp.directive.name); - Cpp.directive.name = NULL; - } + if (Cpp.directive.name != NULL) + { + vStringDelete (Cpp.directive.name); + Cpp.directive.name = NULL; + } }
extern void cppBeginStatement (void) { - Cpp.resolveRequired = TRUE; + Cpp.resolveRequired = TRUE; }
extern void cppEndStatement (void) { - Cpp.resolveRequired = FALSE; + Cpp.resolveRequired = FALSE; }
/* @@ -152,100 +162,96 @@ */ extern void cppUngetc (const int c) { - Assert (Cpp.ungetch2 == '\0'); - Cpp.ungetch2 = Cpp.ungetch; - Cpp.ungetch = c; + Assert (Cpp.ungetch2 == '\0'); + Cpp.ungetch2 = Cpp.ungetch; + Cpp.ungetch = c; }
/* Reads a directive, whose first character is given by "c", into "name". */ static boolean readDirective (int c, char *const name, unsigned int maxLength) { - unsigned int i; + unsigned int i;
- for (i = 0 ; i < maxLength - 1 ; ++i) - { - if (i > 0) + for (i = 0 ; i < maxLength - 1 ; ++i) { - c = fileGetc (); - if (c == EOF || ! isalpha (c)) - { - fileUngetc (c); - break; - } + if (i > 0) + { + c = fileGetc (); + if (c == EOF || ! isalpha (c)) + { + fileUngetc (c); + break; + } + } + name [i] = c; } - name [i] = c; - } - name [i] = '\0'; /* null terminate */ + name [i] = '\0'; /* null terminate */
- return (boolean) isspacetab (c); + return (boolean) isspacetab (c); }
/* Reads an identifier, whose first character is given by "c", into "tag", * together with the file location and corresponding line number. */ -static boolean readDefineTag (int c, vString *const name, - boolean *const parameterized) +static void readIdentifier (int c, vString *const name) { - vStringClear (name); - do - { - vStringPut (name, c); - } while (c = fileGetc (), (c != EOF && isident (c))); - fileUngetc (c); - vStringPut (name, '\0'); - - *parameterized = (boolean) (c == '('); - return (boolean) (isspace (c) || c == '('); + vStringClear (name); + do + { + vStringPut (name, c); + } while (c = fileGetc (), (c != EOF && isident (c))); + fileUngetc (c); + vStringTerminate (name); }
static conditionalInfo *currentConditional (void) { - return &Cpp.directive.ifdef [Cpp.directive.nestLevel]; + return &Cpp.directive.ifdef [Cpp.directive.nestLevel]; }
static boolean isIgnore (void) { - return Cpp.directive.ifdef [Cpp.directive.nestLevel].ignoring; + return Cpp.directive.ifdef [Cpp.directive.nestLevel].ignoring; }
static boolean setIgnore (const boolean ignore) { - return Cpp.directive.ifdef [Cpp.directive.nestLevel].ignoring = ignore; + return Cpp.directive.ifdef [Cpp.directive.nestLevel].ignoring = ignore; }
static boolean isIgnoreBranch (void) { - conditionalInfo *const ifdef = currentConditional (); + conditionalInfo *const ifdef = currentConditional ();
- /* Force a single branch if an incomplete statement is discovered - * en route. This may have allowed earlier branches containing complete - * statements to be followed, but we must follow no further branches. - */ - if (Cpp.resolveRequired && ! BraceFormat) - ifdef->singleBranch = TRUE; + /* Force a single branch if an incomplete statement is discovered + * en route. This may have allowed earlier branches containing complete + * statements to be followed, but we must follow no further branches. + */ + if (Cpp.resolveRequired && ! BraceFormat) + ifdef->singleBranch = TRUE;
- /* We will ignore this branch in the following cases: - * - * 1. We are ignoring all branches (conditional was within an ignored - * branch of the parent conditional) - * 2. A branch has already been chosen and either of: - * a. A statement was incomplete upon entering the conditional - * b. A statement is incomplete upon encountering a branch - */ - return (boolean) (ifdef->ignoreAllBranches || - (ifdef->branchChosen && ifdef->singleBranch)); + /* We will ignore this branch in the following cases: + * + * 1. We are ignoring all branches (conditional was within an ignored + * branch of the parent conditional) + * 2. A branch has already been chosen and either of: + * a. A statement was incomplete upon entering the conditional + * b. A statement is incomplete upon encountering a branch + */ + return (boolean) (ifdef->ignoreAllBranches || + (ifdef->branchChosen && ifdef->singleBranch)); }
static void chooseBranch (void) { - if (! BraceFormat) - { - conditionalInfo *const ifdef = currentConditional (); + if (! BraceFormat) + { + conditionalInfo *const ifdef = currentConditional ();
- ifdef->branchChosen = (boolean) (ifdef->singleBranch || - Cpp.resolveRequired); - } + ifdef->branchChosen = (boolean) (ifdef->singleBranch || + Cpp.resolveRequired); + } }
/* Pushes one nesting level for an #if directive, indicating whether or not @@ -253,141 +259,155 @@ */ static boolean pushConditional (const boolean firstBranchChosen) { - const boolean ignoreAllBranches = isIgnore (); /* current ignore */ - boolean ignoreBranch = FALSE; + const boolean ignoreAllBranches = isIgnore (); /* current ignore */ + boolean ignoreBranch = FALSE;
- if (Cpp.directive.nestLevel < (unsigned int) MaxCppNestingLevel - 1) - { - conditionalInfo *ifdef; + if (Cpp.directive.nestLevel < (unsigned int) MaxCppNestingLevel - 1) + { + conditionalInfo *ifdef;
- ++Cpp.directive.nestLevel; - ifdef = currentConditional (); + ++Cpp.directive.nestLevel; + ifdef = currentConditional ();
- /* We take a snapshot of whether there is an incomplete statement in - * progress upon encountering the preprocessor conditional. If so, - * then we will flag that only a single branch of the conditional - * should be followed. - */ - ifdef->ignoreAllBranches= ignoreAllBranches; - ifdef->singleBranch = Cpp.resolveRequired; - ifdef->branchChosen = firstBranchChosen; - ifdef->ignoring = (boolean) (ignoreAllBranches || ( - ! firstBranchChosen && ! BraceFormat && - (ifdef->singleBranch || !Option.if0))); - ignoreBranch = ifdef->ignoring; - } - return ignoreBranch; + /* We take a snapshot of whether there is an incomplete statement in + * progress upon encountering the preprocessor conditional. If so, + * then we will flag that only a single branch of the conditional + * should be followed. + */ + ifdef->ignoreAllBranches = ignoreAllBranches; + ifdef->singleBranch = Cpp.resolveRequired; + ifdef->branchChosen = firstBranchChosen; + ifdef->ignoring = (boolean) (ignoreAllBranches || ( + ! firstBranchChosen && ! BraceFormat && + (ifdef->singleBranch || !Option.if0))); + ignoreBranch = ifdef->ignoring; + } + return ignoreBranch; }
/* Pops one nesting level for an #endif directive. */ static boolean popConditional (void) { - if (Cpp.directive.nestLevel > 0) - --Cpp.directive.nestLevel; + if (Cpp.directive.nestLevel > 0) + --Cpp.directive.nestLevel;
- return isIgnore (); + return isIgnore (); }
-static void makeDefineTag (const char *const name, boolean parameterized) +static void makeDefineTag (const char *const name) { - const boolean isFileScope = (boolean) (! isHeaderFile ()); + const boolean isFileScope = (boolean) (! isHeaderFile ());
- if (includingDefineTags () && - (! isFileScope || Option.include.fileScope)) - { - tagEntryInfo e; - - initTagEntry (&e, name); - - e.lineNumberEntry = (boolean) (Option.locate != EX_PATTERN); - e.isFileScope = isFileScope; - e.truncateLine = TRUE; - e.kindName = "macro"; - e.kind = 'd'; - if (parameterized) - e.extensionFields.arglist = getArglistFromPos(getInputFilePosition() - , e.name); - makeTagEntry (&e); - if (parameterized) - free((char *) e.extensionFields.arglist); - } + if (includingDefineTags () && + (! isFileScope || Option.include.fileScope)) + { + tagEntryInfo e; + initTagEntry (&e, name); + e.lineNumberEntry = (boolean) (Option.locate != EX_PATTERN); + e.isFileScope = isFileScope; + e.truncateLine = TRUE; + e.kindName = "macro"; + e.kind = 'd'; + makeTagEntry (&e); + } }
static void directiveDefine (const int c) { - boolean parameterized; + if (isident1 (c)) + { + readIdentifier (c, Cpp.directive.name); + if (! isIgnore ()) + makeDefineTag (vStringValue (Cpp.directive.name)); + } + Cpp.directive.state = DRCTV_NONE; +}
- if (isident1 (c)) - { - readDefineTag (c, Cpp.directive.name, ¶meterized); - if (! isIgnore ()) - /// TODO - // the second argument need to be tested, not sure if TRUE is correct - makeDefineTag (vStringValue (Cpp.directive.name), TRUE); - } - Cpp.directive.state = DRCTV_NONE; +static void directivePragma (int c) +{ + if (isident1 (c)) + { + readIdentifier (c, Cpp.directive.name); + if (stringMatch (vStringValue (Cpp.directive.name), "weak")) + { + /* generate macro tag for weak name */ + do + { + c = fileGetc (); + } while (c == SPACE); + if (isident1 (c)) + { + readIdentifier (c, Cpp.directive.name); + makeDefineTag (vStringValue (Cpp.directive.name)); + } + } + } + Cpp.directive.state = DRCTV_NONE; }
static boolean directiveIf (const int c) { - const boolean ignore = pushConditional ((boolean) (c != '0')); + const boolean ignore = pushConditional ((boolean) (c != '0'));
- Cpp.directive.state = DRCTV_NONE; + Cpp.directive.state = DRCTV_NONE;
- return ignore; + return ignore; }
static boolean directiveHash (const int c) { - boolean ignore = FALSE; - char directive [MaxDirectiveName]; - DebugStatement ( const boolean ignore0 = isIgnore (); ) + boolean ignore = FALSE; + char directive [MaxDirectiveName]; + DebugStatement ( const boolean ignore0 = isIgnore (); )
- readDirective (c, directive, MaxDirectiveName); - if (stringMatch (directive, "define")) - Cpp.directive.state = DRCTV_DEFINE; - else if (stringMatch (directive, "undef")) - Cpp.directive.state = DRCTV_UNDEF; - else if (strncmp (directive, "if", (size_t) 2) == 0) - Cpp.directive.state = DRCTV_IF; - else if (stringMatch (directive, "elif") || - stringMatch (directive, "else")) - { - ignore = setIgnore (isIgnoreBranch ()); - if (! ignore && stringMatch (directive, "else")) - chooseBranch (); - Cpp.directive.state = DRCTV_NONE; - DebugStatement ( if (ignore != ignore0) debugCppIgnore (ignore); ) - } - else if (stringMatch (directive, "endif")) - { - DebugStatement ( debugCppNest (FALSE, Cpp.directive.nestLevel); ) - ignore = popConditional (); - Cpp.directive.state = DRCTV_NONE; - DebugStatement ( if (ignore != ignore0) debugCppIgnore (ignore); ) - } - else /* "pragma", etc. */ - Cpp.directive.state = DRCTV_NONE; + readDirective (c, directive, MaxDirectiveName); + if (stringMatch (directive, "define")) + Cpp.directive.state = DRCTV_DEFINE; + else if (stringMatch (directive, "undef")) + Cpp.directive.state = DRCTV_UNDEF; + else if (strncmp (directive, "if", (size_t) 2) == 0) + Cpp.directive.state = DRCTV_IF; + else if (stringMatch (directive, "elif") || + stringMatch (directive, "else")) + { + ignore = setIgnore (isIgnoreBranch ()); + if (! ignore && stringMatch (directive, "else")) + chooseBranch (); + Cpp.directive.state = DRCTV_NONE; + DebugStatement ( if (ignore != ignore0) debugCppIgnore (ignore); ) + } + else if (stringMatch (directive, "endif")) + { + DebugStatement ( debugCppNest (FALSE, Cpp.directive.nestLevel); ) + ignore = popConditional (); + Cpp.directive.state = DRCTV_NONE; + DebugStatement ( if (ignore != ignore0) debugCppIgnore (ignore); ) + } + else if (stringMatch (directive, "pragma")) + Cpp.directive.state = DRCTV_PRAGMA; + else + Cpp.directive.state = DRCTV_NONE;
- return ignore; + return ignore; }
/* Handles a pre-processor directive whose first character is given by "c". */ static boolean handleDirective (const int c) { - boolean ignore = isIgnore (); + boolean ignore = isIgnore ();
- switch (Cpp.directive.state) - { - case DRCTV_NONE: ignore = isIgnore (); break; - case DRCTV_DEFINE: directiveDefine (c); break; - case DRCTV_HASH: ignore = directiveHash (c); break; - case DRCTV_IF: ignore = directiveIf (c); break; - case DRCTV_UNDEF: directiveDefine (c); break; - } - return ignore; + switch (Cpp.directive.state) + { + case DRCTV_NONE: ignore = isIgnore (); break; + case DRCTV_DEFINE: directiveDefine (c); break; + case DRCTV_HASH: ignore = directiveHash (c); break; + case DRCTV_IF: ignore = directiveIf (c); break; + case DRCTV_PRAGMA: directivePragma (c); break; + case DRCTV_UNDEF: directiveDefine (c); break; + } + return ignore; }
/* Called upon reading of a slash ('/') characters, determines whether a @@ -395,101 +415,111 @@ */ static Comment isComment (void) { - Comment comment; - const int next = fileGetc (); + Comment comment; + const int next = fileGetc ();
- if (next == '*') - comment = COMMENT_C; - else if (next == '/') - comment = COMMENT_CPLUS; - else - { - fileUngetc (next); - comment = COMMENT_NONE; - } - return comment; + if (next == '*') + comment = COMMENT_C; + else if (next == '/') + comment = COMMENT_CPLUS; + else + { + fileUngetc (next); + comment = COMMENT_NONE; + } + return comment; }
/* Skips over a C style comment. According to ANSI specification a comment - * is treated as white space, so we perform this subsitution. + * is treated as white space, so we perform this substitution. */ -static int skipOverCComment (void) +int skipOverCComment (void) { - int c = fileGetc (); + int c = fileGetc ();
- while (c != EOF) - { - if (c != '*') - c = fileGetc (); - else + while (c != EOF) { - const int next = fileGetc (); + if (c != '*') + c = fileGetc (); + else + { + const int next = fileGetc ();
- if (next != '/') - c = next; - else - { - c = ' '; /* replace comment with space */ - break; - } + if (next != '/') + c = next; + else + { + c = SPACE; /* replace comment with space */ + break; + } + } } - } - return c; + return c; }
/* Skips over a C++ style comment. */ static int skipOverCplusComment (void) { - int c; + int c;
- while ((c = fileGetc ()) != EOF) - { - if (c == BACKSLASH) - fileGetc (); /* throw away next character, too */ - else if (c == NEWLINE) - break; - } - return c; + while ((c = fileGetc ()) != EOF) + { + if (c == BACKSLASH) + fileGetc (); /* throw away next character, too */ + else if (c == NEWLINE) + break; + } + return c; }
/* Skips to the end of a string, returning a special character to * symbolically represent a generic string. */ -static int skipToEndOfString (void) +static int skipToEndOfString (boolean ignoreBackslash) { - int c; + int c;
- while ((c = fileGetc ()) != EOF) - { - if (c == BACKSLASH) - fileGetc (); /* throw away next character, too */ - else if (c == DOUBLE_QUOTE) - break; - } - return STRING_SYMBOL; /* symbolic representation of string */ + while ((c = fileGetc ()) != EOF) + { + if (c == BACKSLASH && ! ignoreBackslash) + fileGetc (); /* throw away next character, too */ + else if (c == DOUBLE_QUOTE) + break; + } + return STRING_SYMBOL; /* symbolic representation of string */ }
/* Skips to the end of the three (possibly four) 'c' sequence, returning a * special character to symbolically represent a generic character. + * Also detects Vera numbers that include a base specifier (ie. 'b1010). */ static int skipToEndOfChar (void) { - int c; + int c; + int count = 0, veraBase = '\0';
- while ((c = fileGetc ()) != EOF) - { - if (c == BACKSLASH) - fileGetc (); /* throw away next character, too */ - else if (c == SINGLE_QUOTE) - break; - else if (c == NEWLINE) + while ((c = fileGetc ()) != EOF) { - fileUngetc (c); - break; + ++count; + if (c == BACKSLASH) + fileGetc (); /* throw away next character, too */ + else if (c == SINGLE_QUOTE) + break; + else if (c == NEWLINE) + { + fileUngetc (c); + break; + } + else if (count == 1 && strchr ("DHOB", toupper (c)) != NULL) + veraBase = c; + else if (veraBase != '\0' && ! isalnum (c)) + { + fileUngetc (c); + break; + } } - } - return CHAR_SYMBOL; /* symbolic representation of character */ + return CHAR_SYMBOL; /* symbolic representation of character */ }
/* This function returns the next character, stripping out comments, @@ -499,265 +529,137 @@ */ extern int cppGetc (void) { - boolean directive = FALSE; - boolean ignore = FALSE; - int c; + boolean directive = FALSE; + boolean ignore = FALSE; + int c;
- if (Cpp.ungetch != '\0') - { - c = Cpp.ungetch; - Cpp.ungetch = Cpp.ungetch2; - Cpp.ungetch2 = '\0'; - return c; /* return here to avoid re-calling debugPutc () */ - } - else do - { - c = fileGetc (); -process: - switch (c) + if (Cpp.ungetch != '\0') { - case EOF: - ignore = FALSE; - directive = FALSE; - break; - - case TAB: - case SPACE: - break; /* ignore most white space */ - - case NEWLINE: - if (directive && ! ignore) - directive = FALSE; - Cpp.directive.accept = TRUE; - break; - - case DOUBLE_QUOTE: - Cpp.directive.accept = FALSE; - c = skipToEndOfString (); - break; - - case '#': - if (Cpp.directive.accept) + c = Cpp.ungetch; + Cpp.ungetch = Cpp.ungetch2; + Cpp.ungetch2 = '\0'; + return c; /* return here to avoid re-calling debugPutc () */ + } + else do + { + c = fileGetc (); +process: + switch (c) { - directive = TRUE; - Cpp.directive.state = DRCTV_HASH; - Cpp.directive.accept = FALSE; - } - break; + case EOF: + ignore = FALSE; + directive = FALSE; + break;
- case SINGLE_QUOTE: - Cpp.directive.accept = FALSE; - c = skipToEndOfChar (); - break; + case TAB: + case SPACE: + break; /* ignore most white space */
- case '/': - { - const Comment comment = isComment (); + case NEWLINE: + if (directive && ! ignore) + directive = FALSE; + Cpp.directive.accept = TRUE; + break;
- if (comment == COMMENT_C) - c = skipOverCComment (); - else if (comment == COMMENT_CPLUS) - { - c = skipOverCplusComment (); - if (c == NEWLINE) - fileUngetc (c); - } - else - Cpp.directive.accept = FALSE; - break; - } + case DOUBLE_QUOTE: + Cpp.directive.accept = FALSE; + c = skipToEndOfString (FALSE); + break;
- case BACKSLASH: - { - int next = fileGetc (); + case '#': + if (Cpp.directive.accept) + { + directive = TRUE; + Cpp.directive.state = DRCTV_HASH; + Cpp.directive.accept = FALSE; + } + break;
- if (next == NEWLINE) - continue; - else if (next == '?') - cppUngetc (next); - else - fileUngetc (next); - break; - } + case SINGLE_QUOTE: + Cpp.directive.accept = FALSE; + c = skipToEndOfChar (); + break;
- case '?': - { - int next = fileGetc (); - if (next != '?') - fileUngetc (next); - else - { - next = fileGetc (); - switch (next) - { - case '(': c = '['; break; - case ')': c = ']'; break; - case '<': c = '{'; break; - case '>': c = '}'; break; - case '/': c = BACKSLASH; goto process; - case '!': c = '|'; break; - case SINGLE_QUOTE: c = '^'; break; - case '-': c = '~'; break; - case '=': c = '#'; goto process; - default: - fileUngetc (next); - cppUngetc ('?'); - break; - } - } - } break; + case '/': + { + const Comment comment = isComment ();
- default: - Cpp.directive.accept = FALSE; - if (directive) - ignore = handleDirective (c); - break; - } - } while (directive || ignore); + if (comment == COMMENT_C) + c = skipOverCComment (); + else if (comment == COMMENT_CPLUS) + { + c = skipOverCplusComment (); + if (c == NEWLINE) + fileUngetc (c); + } + else + Cpp.directive.accept = FALSE; + break; + }
- DebugStatement ( debugPutc (DEBUG_CPP, c); ) - DebugStatement ( if (c == NEWLINE) - debugPrintf (DEBUG_CPP, "%6ld: ", getInputLineNumber () + 1); ) + case BACKSLASH: + { + int next = fileGetc ();
- return c; -} + if (next == NEWLINE) + continue; + else if (next == '?') + cppUngetc (next); + else + fileUngetc (next); + break; + }
- -extern char *getArglistFromPos(fpos_t startPosition, const char *tokenName) -{ - fpos_t originalPosition; - char *result = NULL; - char *arglist = NULL; - long pos1, pos2 = ftell(File.fp); - - fgetpos(File.fp, &originalPosition); - fsetpos(File.fp, &startPosition); - pos1 = ftell(File.fp); - if (pos2 > pos1) - { - result = (char *) g_malloc(sizeof(char ) * (pos2 - pos1 + 2)); - if (result != NULL) - { - fread(result, sizeof(char), pos2 - pos1 + 1, File.fp); - result[pos2-pos1+1] = '\0'; - arglist = getArglistFromStr(result, tokenName); - free(result); - } - } - fsetpos(File.fp, &originalPosition); - return arglist; -} - -typedef enum -{ - st_none_t, - st_escape_t, - st_c_comment_t, - st_cpp_comment_t, - st_double_quote_t, - st_single_quote_t -} ParseState; - -static void stripCodeBuffer(char *buf) -{ - int i = 0, pos = 0; - ParseState state = st_none_t, prev_state = st_none_t; - - while (buf[i] != '\0') - { - switch(buf[i]) - { - case '/': - if (st_none_t == state) + case '?': + { + int next = fileGetc (); + if (next != '?') + fileUngetc (next); + else { - /* Check if this is the start of a comment */ - if (buf[i+1] == '*') /* C comment */ - state = st_c_comment_t; - else if (buf[i+1] == '/') /* C++ comment */ - state = st_cpp_comment_t; - else /* Normal character */ - buf[pos++] = '/'; - } - else if (st_c_comment_t == state) - { - /* Check if this is the end of a C comment */ - if (buf[i-1] == '*') + next = fileGetc (); + switch (next) { - if ((pos > 0) && (buf[pos-1] != ' ')) - buf[pos++] = ' '; - state = st_none_t; + case '(': c = '['; break; + case ')': c = ']'; break; + case '<': c = '{'; break; + case '>': c = '}'; break; + case '/': c = BACKSLASH; goto process; + case '!': c = '|'; break; + case SINGLE_QUOTE: c = '^'; break; + case '-': c = '~'; break; + case '=': c = '#'; goto process; + default: + fileUngetc (next); + cppUngetc ('?'); + break; } } - break; - case '"': - if (st_none_t == state) - state = st_double_quote_t; - else if (st_double_quote_t == state) - state = st_none_t; - break; - case ''': - if (st_none_t == state) - state = st_single_quote_t; - else if (st_single_quote_t == state) - state = st_none_t; - break; + } break; + default: - if ((buf[i] == '\') && (st_escape_t != state)) + if (c == '@' && Cpp.hasAtLiteralStrings) { - prev_state = state; - state = st_escape_t; - } - else if (st_escape_t == state) - { - state = prev_state; - prev_state = st_none_t; - } - else if ((buf[i] == '\n') && (st_cpp_comment_t == state)) - { - if ((pos > 0) && (buf[pos-1] != ' ')) - buf[pos++] = ' '; - state = st_none_t; - } - else if (st_none_t == state) - { - if (isspace(buf[i])) + int next = fileGetc (); + if (next == DOUBLE_QUOTE) { - if ((pos > 0) && (buf[pos-1] != ' ')) - buf[pos++] = ' '; + Cpp.directive.accept = FALSE; + c = skipToEndOfString (TRUE); + break; } - else - buf[pos++] = buf[i]; } + Cpp.directive.accept = FALSE; + if (directive) + ignore = handleDirective (c); break; } - ++i; - } - buf[pos] = '\0'; - return; -} + } while (directive || ignore);
-extern char *getArglistFromStr(char *buf, const char *name) -{ - char *start, *end; - int level; - if ((NULL == buf) || (NULL == name) || ('\0' == name[0])) - return NULL; - stripCodeBuffer(buf); - if (NULL == (start = strstr(buf, name))) - return NULL; - if (NULL == (start = strchr(start, '('))) - return NULL; - for (level = 1, end = start + 1; level > 0; ++end) - { - if ('\0' == *end) - break; - else if ('(' == *end) - ++ level; - else if (')' == *end) - -- level; - } - *end = '\0'; - return strdup(start); + DebugStatement ( debugPutc (DEBUG_CPP, c); ) + DebugStatement ( if (c == NEWLINE) + debugPrintf (DEBUG_CPP, "%6ld: ", getInputLineNumber () + 1); ) + + return c; }
-/* vi:set tabstop=8 shiftwidth=4: */ +/* vi:set tabstop=4 shiftwidth=4: */
Modified: trunk/tagmanager/get.h =================================================================== --- trunk/tagmanager/get.h 2007-06-20 12:42:06 UTC (rev 1633) +++ trunk/tagmanager/get.h 2007-06-22 17:22:07 UTC (rev 1634) @@ -1,6 +1,7 @@ /* +* $Id$ * -* Copyright (c) 1998-2001, Darren Hiebert +* Copyright (c) 1998-2002, Darren Hiebert * * This source code is released for free distribution under the terms of the * GNU General Public License. @@ -13,7 +14,7 @@ /* * INCLUDE FILES */ -#include "general.h" /* must always come first */ +#include "general.h" /* must always come first */
#include "ctags.h" /* to define langType */
@@ -36,14 +37,14 @@ */ extern boolean isBraceFormat (void); extern unsigned int getDirectiveNestLevel (void); -extern void cppInit (const boolean state); +extern void cppInit (const boolean state, const boolean hasAtLiteralStrings); extern void cppTerminate (void); extern void cppBeginStatement (void); extern void cppEndStatement (void); extern void cppUngetc (const int c); extern int cppGetc (void); -extern char *getArglistFromPos(fpos_t startPosition, const char *tokenName); -extern char *getArglistFromStr(char *buf, const char *name); -#endif /* _GET_H */ +extern int skipOverCComment (void);
-/* vi:set tabstop=8 shiftwidth=4: */ +#endif /* _GET_H */ + +/* vi:set tabstop=4 shiftwidth=4: */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.