SF.net SVN: geany: [741] trunk
ntrel at users.sourceforge.net
ntrel at xxxxx
Fri Aug 18 19:57:08 UTC 2006
Revision: 741
Author: ntrel
Date: 2006-08-18 12:57:02 -0700 (Fri, 18 Aug 2006)
ViewCVS: http://svn.sourceforge.net/geany/?rev=741&view=rev
Log Message:
-----------
Merged tagmanager/d.c with tagmanager/c.c, which also adds user function calltips support for D
Modified Paths:
--------------
trunk/ChangeLog
trunk/tagmanager/Makefile.am
trunk/tagmanager/c.c
Removed Paths:
-------------
trunk/tagmanager/d.c
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-08-18 17:44:46 UTC (rev 740)
+++ trunk/ChangeLog 2006-08-18 19:57:02 UTC (rev 741)
@@ -13,8 +13,11 @@
Add dialogs_show_question_full for custom buttons and extra text.
Don't show message dialogs in the window manager taskbar.
* src/utils.c: Use Reload button for utils_check_disk_status dialog.
- * src/callbacks.c: Use Reload button for reload dialog.
+ * src/callbacks.c: Improve Reload and Quit dialog.
Share on_reload_as_activate code for reloading.
+* tagmanager/d.c, tagmanager/c.c, tagmanager/Makefile.am:
+ Merged tagmanager/d.c with tagmanager/c.c, which also adds user
+ function calltips support for D.
2006-08-17 Nick Treleaven <nick.treleaven at btinternet.com>
Modified: trunk/tagmanager/Makefile.am
===================================================================
--- trunk/tagmanager/Makefile.am 2006-08-18 17:44:46 UTC (rev 740)
+++ trunk/tagmanager/Makefile.am 2006-08-18 19:57:02 UTC (rev 741)
@@ -27,7 +27,6 @@
args.c\
args.h\
c.c\
- d.c\
conf.c\
css.c\
docbook.c\
Modified: trunk/tagmanager/c.c
===================================================================
--- trunk/tagmanager/c.c 2006-08-18 17:44:46 UTC (rev 740)
+++ trunk/tagmanager/c.c 2006-08-18 19:57:02 UTC (rev 741)
@@ -5,7 +5,7 @@
* 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 and Java
* source files.
*/
@@ -233,6 +233,7 @@
static langType Lang_c;
static langType Lang_cpp;
static langType Lang_java;
+static langType Lang_d;
/* Used to index into the CKinds table. */
typedef enum {
@@ -819,7 +820,7 @@
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)) && st->scope == SCOPE_FRIEND)
result = "friend";
else if (st->member.access != ACCESS_UNDEFINED)
result = accessString (st->member.access);
@@ -866,7 +867,7 @@
vStringValue (st->parentClasses);
}
if (st->implementation != IMP_DEFAULT &&
- (isLanguage (Lang_cpp) || isLanguage (Lang_java)))
+ (isLanguage (Lang_cpp) || isLanguage (Lang_java) || isLanguage (Lang_d)))
{
tag->extensionFields.implementation =
implementationString (st->implementation);
@@ -900,7 +901,7 @@
static void addContextSeparator (vString *const scope)
{
- if (isLanguage (Lang_c) || isLanguage (Lang_cpp))
+ if (isLanguage (Lang_c) || isLanguage (Lang_cpp) || isLanguage (Lang_d))
vStringCatS (scope, "::");
else if (isLanguage (Lang_java))
vStringCatS (scope, ".");
@@ -1426,7 +1427,7 @@
{
if (isMember (st))
{
- if (isLanguage (Lang_cpp))
+ if (isLanguage (Lang_cpp) || isLanguage (Lang_d))
{
int c = skipToNonWhite ();
@@ -1981,7 +1982,7 @@
{
if (vStringLength (st->context->name) > 0)
{
- if (isLanguage (Lang_c) || isLanguage (Lang_cpp))
+ if (isLanguage (Lang_c) || isLanguage (Lang_cpp) || isLanguage (Lang_d))
vStringCatS (st->context->name, "::");
else if (isLanguage (Lang_java))
vStringCatS (st->context->name, ".");
@@ -2004,7 +2005,7 @@
else
{
cppUngetc (c);
- if (isLanguage (Lang_cpp) && (
+ if ((isLanguage (Lang_cpp) || isLanguage (Lang_d)) && (
st->declaration == DECL_CLASS || st->declaration == DECL_STRUCT))
{
readParents (st, ':');
@@ -2403,6 +2404,12 @@
buildKeywordHash (language, 2);
}
+static void initializeDParser (const langType language)
+{
+ Lang_d = language;
+ buildKeywordHash (language, 17);
+}
+
extern parserDefinition* CParser (void)
{
static const char *const extensions [] = { "c", "pc", "sc", NULL };
@@ -2446,4 +2453,17 @@
return def;
}
+extern parserDefinition* DParser (void)
+{
+ static const char *const extensions [] = { "d", "di", NULL };
+ parserDefinition* def = parserNew ("D");
+ def->kinds = CKinds;
+ def->kindCount = KIND_COUNT (CKinds);
+ def->extensions = extensions;
+ def->parser2 = findCTags;
+ def->initialize = initializeDParser;
+ return def;
+}
+
+
/* vi:set tabstop=8 shiftwidth=4: */
Deleted: trunk/tagmanager/d.c
===================================================================
--- trunk/tagmanager/d.c 2006-08-18 17:44:46 UTC (rev 740)
+++ trunk/tagmanager/d.c 2006-08-18 19:57:02 UTC (rev 741)
@@ -1,2303 +0,0 @@
-/*
-*
-* Copyright (c) 1996-2001, Darren Hiebert
-* Copyright (c) 2006, Enrico Tröger
-*
-* 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 D source files(based on c.c).
-*/
-
-/*
-* INCLUDE FILES
-*/
-#include "general.h" /* must always come first */
-
-#include <string.h>
-#include <setjmp.h>
-//#include <glib.h>
-
-#include "entry.h"
-#include "get.h"
-#include "keyword.h"
-#include "main.h"
-#include "parse.h"
-#include "read.h"
-#include "options.h"
-
-/*
-* MACROS
-*/
-#define MaxFields 6
-
-#define stringValue(a) #a
-#define activeToken(st) ((st)->token [(int) (st)->tokenIndex])
-#define parentDecl(st) ((st)->parent == NULL ? \
- DECL_NONE : (st)->parent->declaration)
-#define isType(token,t) (boolean) ((token)->type == (t))
-#define insideEnumBody(st) (boolean) ((st)->parent == NULL ? FALSE : \
- ((st)->parent->declaration == DECL_ENUM))
-#define isExternCDecl(st,c) (boolean) ((c) == STRING_SYMBOL && \
- ! (st)->haveQualifyingName && (st)->scope == SCOPE_EXTERN)
-
-#define isOneOf(c,s) (boolean) (strchr ((s), (c)) != NULL)
-
-/*
-* DATA DECLARATIONS
-*/
-
-enum { NumTokens = 3 };
-
-typedef enum eException {
- ExceptionNone, ExceptionEOF, ExceptionFormattingError,
- ExceptionBraceFormattingError
-} exception_t;
-
-/* 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_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_USING,
- KEYWORD_VIRTUAL, KEYWORD_VOID, KEYWORD_VOLATILE,
- KEYWORD_WCHAR_T
-} 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 */
-} keywordDesc;
-
-/* Used for reporting the type of object parsed by nextToken ().
- */
-typedef enum eTokenType {
- TOKEN_NONE, /* none */
- TOKEN_ARGS, /* a parenthetical pair and its contents */
- TOKEN_BRACE_CLOSE,
- TOKEN_BRACE_OPEN,
- 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_COUNT
-} tokenType;
-
-/* This describes the scoping of the current statement.
- */
-typedef enum eTagScope {
- SCOPE_GLOBAL, /* no storage class specified */
- SCOPE_STATIC, /* static storage class */
- SCOPE_EXTERN, /* external storage class */
- SCOPE_FRIEND, /* declares access only */
- SCOPE_TYPEDEF, /* scoping depends upon context */
- SCOPE_COUNT
-} tagScope;
-
-typedef enum eDeclaration {
- DECL_NONE,
- DECL_BASE, /* base type (default) */
- DECL_CLASS,
- DECL_ENUM,
- DECL_FUNCTION,
- DECL_IGNORE, /* non-taggable "declaration" */
- DECL_INTERFACE,
- DECL_NAMESPACE,
- DECL_NOMANGLE, /* C++ name demangling block */
- DECL_PACKAGE,
- DECL_STRUCT,
- DECL_UNION,
- DECL_COUNT
-} declType;
-
-typedef enum eVisibilityType {
- ACCESS_UNDEFINED,
- ACCESS_PRIVATE,
- ACCESS_PROTECTED,
- ACCESS_PUBLIC,
- ACCESS_COUNT
-} accessType;
-
-/* Information about the parent class of a member (if any).
- */
-typedef struct sMemberInfo {
- accessType access; /* access of current statement */
- accessType accessDefault; /* access default for current statement */
-} memberInfo;
-
-typedef struct sTokenInfo {
- tokenType type;
- keywordId keyword;
- vString* name; /* the name of the token */
- unsigned long lineNumber; /* line number of tag */
- fpos_t filePosition; /* file position of line containing name */
-} tokenInfo;
-
-
-typedef enum eImplementation {
- IMP_DEFAULT,
- IMP_ABSTRACT,
- IMP_VIRTUAL,
- IMP_PURE_VIRTUAL,
- IMP_COUNT
-} impType;
-
-/* Describes the statement currently undergoing analysis.
- */
-typedef struct sStatementInfo {
- tagScope scope;
- declType declaration; /* specifier associated with TOKEN_SPEC */
- boolean gotName; /* was a name parsed yet? */
- boolean haveQualifyingName; /* do we have a name we are considering? */
- boolean gotParenName; /* was a name inside parentheses parsed yet? */
- boolean gotArgs; /* was a list of parameters parsed yet? */
- boolean isPointer; /* is 'name' a pointer? */
- impType implementation; /* abstract or concrete implementation? */
- unsigned int tokenIndex; /* currently active token */
- tokenInfo* token [(int) NumTokens];
- tokenInfo* context; /* accumulated scope of current statement */
- tokenInfo* blockName; /* name of current block */
- 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.
- */
-typedef enum eTagType {
- TAG_UNDEFINED,
- TAG_CLASS, /* class name */
- TAG_ENUM, /* enumeration name */
- TAG_ENUMERATOR, /* enumerator (enumeration value) */
- TAG_FIELD, /* field (Java) */
- TAG_FUNCTION, /* function definition */
- TAG_INTERFACE, /* interface declaration */
- TAG_MEMBER, /* structure, class or interface member */
- TAG_METHOD, /* method declaration */
- TAG_NAMESPACE, /* namespace name */
- TAG_PACKAGE, /* package name */
- TAG_PROTOTYPE, /* function prototype or declaration */
- TAG_STRUCT, /* structure name */
- TAG_TYPEDEF, /* typedef name */
- TAG_UNION, /* union name */
- TAG_VARIABLE, /* variable definition */
- TAG_EXTERN_VAR, /* external variable declaration */
- TAG_MACRO, /* #define s */
- TAG_COUNT /* must be last */
-} tagType;
-
-typedef struct sParenInfo {
- boolean isPointer;
- boolean isParamList;
- boolean isKnrParamList;
- boolean isNameCandidate;
- boolean invalidContents;
- boolean nestedArgs;
- unsigned int parameterCount;
-} parenInfo;
-
-/*
-* DATA DEFINITIONS
-*/
-
-static jmp_buf Exception;
-
-static langType Lang_d;
-
-/* Used to index into the DKinds table. */
-typedef enum {
- CK_UNDEFINED = -1,
- CK_CLASS, CK_DEFINE, CK_ENUMERATOR, CK_FUNCTION,
- CK_ENUMERATION, CK_MEMBER, CK_NAMESPACE, CK_PROTOTYPE,
- CK_STRUCT, CK_TYPEDEF, CK_UNION, CK_VARIABLE,
- CK_EXTERN_VARIABLE
-} cKind;
-
-static kindOption DKinds [] = {
- { TRUE, 'c', "class", "classes"},
- { TRUE, 'd', "macro", "macro definitions"},
- { TRUE, 'e', "enumerator", "enumerators (values inside an enumeration)"},
- { TRUE, 'f', "function", "function definitions"},
- { TRUE, 'g', "enum", "enumeration names"},
- { 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"},
-};
-
-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 } },
- { "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 } },
- { "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 } }
-};
-
-/*
-* FUNCTION PROTOTYPES
-*/
-static void createTags (const unsigned int nestLevel, statementInfo *const parent);
-
-/*
-* FUNCTION DEFINITIONS
-*/
-
-/* Debugging functions added by Biswa */
-#if DEBUG_C
-static char *tokenTypeName[] = {
- "none", "args", "'}'", "'{'", "','", "'::'", "keyword", "name",
- "package", "paren-name", "';'", "spec", "count"
-};
-
-static char *tagScopeNames[] = {
- "global", "static", "extern", "friend", "typedef", "count"};
-
-static char *declTypeNames[] = {
- "none", "base", "class", "enum", "function", "ignore", "interface",
- "namespace", "nomangle", "package", "struct", "union", "count"};
-
-static char *impTypeNames[] = {
- "default", "abstract", "virtual", "pure-virtual", "count"};
-
-void printToken(const tokenInfo *const token)
-{
- fprintf(stderr, "Type: %s, Keyword: %d, name: %s\n", tokenTypeName[token->type],
- token->keyword, vStringValue(token->name));
-}
-
-void printTagEntry(const tagEntryInfo *tag)
-{
- fprintf(stderr, "Tag: %s (%s) [ impl: %s, scope: %s, type: %s\n", tag->name,
- tag->kindName, tag->extensionFields.implementation, tag->extensionFields.scope[1],
- tag->extensionFields.varType);
-}
-
-void printStatement(const statementInfo *const statement)
-{
- int i;
- statementInfo *st = (statementInfo *) statement;
- while (NULL != st)
- {
- fprintf(stderr, "Statement Info:\n------------------------\n");
- fprintf(stderr, "scope: %s, decl: %s, impl: %s\n", tagScopeNames[st->scope]
- , declTypeNames[st->declaration], impTypeNames[st->implementation]);
- for (i=0; i < NumTokens; ++i)
- {
- fprintf(stderr, "Token %d %s: ", i, (i == st->tokenIndex)?"(current)":"");
- printToken(st->token[i]);
- }
- fprintf(stderr, "Context: ");
- printToken(st->context);
- fprintf(stderr, "Block: ");
- printToken(st->blockName);
- fprintf(stderr, "Parent classes: %s\n", vStringValue(st->parentClasses));
- fprintf(stderr, "First token: ");
- printToken(st->firstToken);
- if (NULL != st->parent)
- fprintf(stderr, "Printing Parent:\n");
- st = st->parent;
- }
- fprintf(stderr, "-----------------------------------------------\n");
-}
-#endif
-
-/* Checks if the token is a base data type (int/log/float/void/etc) */
-static boolean isBaseDataType(const char *name)
-{
- return (boolean) ((0 == strcmp(name, "int")) || (0 == strcmp(name, "char")) ||
- (0 == strcmp(name, "long")) || (0 == strcmp(name, "float")) ||
- (0 == strcmp(name, "double")) || (0 == strcmp(name, "short")) ||
- (0 == strcmp(name, "void")) || (0 == strcmp(name, "bool")));
-}
-
-/*extern boolean includingDefineTags (void)
-{
- return DKinds [CK_DEFINE].enabled;
-}
-*/
-/*
-* Token management
-*/
-
-static void initToken (tokenInfo* const token)
-{
- token->type = TOKEN_NONE;
- token->keyword = KEYWORD_NONE;
- token->lineNumber = getSourceLineNumber ();
- token->filePosition = getInputFilePosition ();
- vStringClear (token->name);
-}
-
-static void advanceToken (statementInfo* const st)
-{
- if (st->tokenIndex >= (unsigned int) NumTokens - 1)
- st->tokenIndex = 0;
- else
- ++st->tokenIndex;
- initToken (st->token [st->tokenIndex]);
-}
-
-static tokenInfo *prevToken (const statementInfo *const st, unsigned int n)
-{
- unsigned int tokenIndex;
- unsigned int num = (unsigned int) NumTokens;
- Assert (n < num);
- tokenIndex = (st->tokenIndex + num - n) % num;
- return st->token [tokenIndex];
-}
-
-static void setToken (statementInfo *const st, const tokenType type)
-{
- tokenInfo *token;
- token = activeToken (st);
- initToken (token);
- token->type = type;
-}
-
-static void retardToken (statementInfo *const st)
-{
- if (st->tokenIndex == 0)
- st->tokenIndex = (unsigned int) NumTokens - 1;
- else
- --st->tokenIndex;
- setToken (st, TOKEN_NONE);
-}
-
-static tokenInfo *newToken (void)
-{
- tokenInfo *const token = xMalloc (1, tokenInfo);
- token->name = vStringNew ();
- initToken (token);
- return token;
-}
-
-static void deleteToken (tokenInfo *const token)
-{
- if (token != NULL)
- {
- vStringDelete (token->name);
- eFree (token);
- }
-}
-
-static const char *accessString (const accessType access)
-{
- static const char *const names [] ={
- "?", "private", "protected", "public", "default"
- };
- Assert (sizeof (names) / sizeof (names [0]) == ACCESS_COUNT);
- Assert ((int) access < ACCESS_COUNT);
- return names [(int) access];
-}
-
-static const char *implementationString (const impType imp)
-{
- static const char *const names [] ={
- "?", "abstract", "virtual", "pure virtual"
- };
- Assert (sizeof (names) / sizeof (names [0]) == IMP_COUNT);
- Assert ((int) imp < IMP_COUNT);
- return names [(int) imp];
-}
-
-/*
-* Debugging functions
-*/
-
-#ifdef TM_DEBUG
-
-#define boolString(c) ((c) ? "TRUE" : "FALSE")
-
-static const char *tokenString (const tokenType type)
-{
- static const char *const names [] = {
- "none", "args", "}", "{", "comma", "double colon", "keyword", "name",
- "package", "paren-name", "semicolon", "specifier"
- };
- Assert (sizeof (names) / sizeof (names [0]) == TOKEN_COUNT);
- Assert ((int) type < TOKEN_COUNT);
- return names [(int) type];
-}
-
-static const char *scopeString (const tagScope scope)
-{
- static const char *const names [] = {
- "global", "static", "extern", "friend", "typedef"
- };
- Assert (sizeof (names) / sizeof (names [0]) == SCOPE_COUNT);
- Assert ((int) scope < SCOPE_COUNT);
- return names [(int) scope];
-}
-
-static const char *declString (const declType declaration)
-{
- static const char *const names [] = {
- "?", "base", "class", "enum", "function", "ignore", "interface",
- "namespace", "no mangle", "package", "struct", "union",
- };
- Assert (sizeof (names) / sizeof (names [0]) == DECL_COUNT);
- Assert ((int) declaration < DECL_COUNT);
- return names [(int) declaration];
-}
-
-static const char *keywordString (const keywordId keyword)
-{
- const size_t count = sizeof (KeywordTable) / sizeof (KeywordTable [0]);
- const char *name = "none";
- size_t i;
- for (i = 0 ; i < count ; ++i)
- {
- const keywordDesc *p = &KeywordTable [i];
-
- if (p->id == keyword)
- {
- name = p->name;
- break;
- }
- }
- return name;
-}
-
-static void __unused__ pt (tokenInfo *const token)
-{
- if (isType (token, TOKEN_NAME))
- printf ("type: %-12s: %-13s line: %lu\n",
- tokenString (token->type), vStringValue (token->name),
- token->lineNumber);
- else if (isType (token, TOKEN_KEYWORD))
- printf ("type: %-12s: %-13s line: %lu\n",
- tokenString (token->type), keywordString (token->keyword),
- token->lineNumber);
- else
- printf ("type: %-12s line: %lu\n",
- tokenString (token->type), token->lineNumber);
-}
-
-static void __unused__ ps (statementInfo *const st)
-{
- unsigned int i;
- printf ("scope: %s decl: %s gotName: %s gotParenName: %s\n",
- scopeString (st->scope), declString (st->declaration),
- boolString (st->gotName), boolString (st->gotParenName));
- printf ("haveQualifyingName: %s\n", boolString (st->haveQualifyingName));
- printf ("access: %s default: %s\n", accessString (st->member.access),
- accessString (st->member.accessDefault));
- printf ("token : ");
- pt (activeToken (st));
- for (i = 1 ; i < (unsigned int) NumTokens ; ++i)
- {
- printf ("prev %u : ", i);
- pt (prevToken (st, i));
- }
- printf ("context: ");
- pt (st->context);
-}
-
-#endif
-
-/*
-* Statement management
-*/
-
-static boolean isContextualKeyword (const tokenInfo *const token)
-{
- boolean result;
- switch (token->keyword)
- {
- case KEYWORD_CLASS:
- case KEYWORD_ENUM:
- case KEYWORD_INTERFACE:
- case KEYWORD_NAMESPACE:
- case KEYWORD_STRUCT:
- case KEYWORD_UNION:
- result = TRUE;
- break;
-
- default: result = FALSE; break;
- }
- return result;
-}
-
-static boolean isContextualStatement (const statementInfo *const st)
-{
- boolean result = FALSE;
- if (st != NULL) 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;
- }
- return result;
-}
-
-static boolean isMember (const statementInfo *const st)
-{
- boolean result;
- if (isType (st->context, TOKEN_NAME))
- result = TRUE;
- else
- result = isContextualStatement (st->parent);
- return result;
-}
-
-static void initMemberInfo (statementInfo *const st)
-{
- accessType accessDefault = ACCESS_UNDEFINED;
-
- if (st->parent != NULL) switch (st->parent->declaration)
- {
- case DECL_ENUM:
- case DECL_NAMESPACE:
- case DECL_UNION:
- accessDefault = ACCESS_UNDEFINED;
- break;
-
- case DECL_CLASS:
- accessDefault = ACCESS_PRIVATE;
- break;
-
- case DECL_INTERFACE:
- case DECL_STRUCT:
- accessDefault = ACCESS_PUBLIC;
- break;
-
- default: break;
- }
- st->member.accessDefault = accessDefault;
- st->member.access = accessDefault;
-}
-
-static void reinitStatement (statementInfo *const st, const boolean partial)
-{
- unsigned int i;
-
- if (! partial)
- {
- st->scope = SCOPE_GLOBAL;
- if (isContextualStatement (st->parent))
- st->declaration = DECL_BASE;
- else
- st->declaration = DECL_NONE;
- }
- st->gotParenName = FALSE;
- st->isPointer = FALSE;
- st->implementation = IMP_DEFAULT;
- st->gotArgs = FALSE;
- st->gotName = FALSE;
- st->haveQualifyingName = FALSE;
- st->tokenIndex = 0;
- st->argEndPosition = 0;
-
- for (i = 0 ; i < (unsigned int) NumTokens ; ++i)
- initToken (st->token [i]);
-
- initToken (st->context);
- initToken (st->blockName);
- vStringClear (st->parentClasses);
-
- /* Init member info.
- */
- if (! partial)
- st->member.access = st->member.accessDefault;
-
- /* Init first token */
- if (!partial)
- initToken(st->firstToken);
-}
-
-static void initStatement (statementInfo *const st, statementInfo *const parent)
-{
- st->parent = parent;
- initMemberInfo (st);
- reinitStatement (st, FALSE);
-}
-
-/*
-* Tag generation functions
-*/
-static cKind dTagKind (const tagType type)
-{
- cKind result = CK_UNDEFINED;
- switch (type)
- {
- case TAG_CLASS: result = CK_CLASS; break;
- case TAG_ENUM: result = CK_ENUMERATION; break;
- case TAG_ENUMERATOR: result = CK_ENUMERATOR; break;
- case TAG_FUNCTION: result = CK_FUNCTION; break;
- case TAG_MEMBER: result = CK_MEMBER; break;
- case TAG_NAMESPACE: result = CK_NAMESPACE; break;
- case TAG_PROTOTYPE: result = CK_PROTOTYPE; break;
- case TAG_STRUCT: result = CK_STRUCT; break;
- case TAG_TYPEDEF: result = CK_TYPEDEF; break;
- case TAG_UNION: result = CK_UNION; break;
- case TAG_VARIABLE: result = CK_VARIABLE; break;
- case TAG_EXTERN_VAR: result = CK_EXTERN_VARIABLE; break;
-
- default: Assert ("Bad C tag type" == NULL); break;
- }
- return result;
-}
-
-static const char *tagName (const tagType type)
-{
- return DKinds [dTagKind (type)].name;
-}
-
-static int tagLetter (const tagType type)
-{
- return DKinds [dTagKind (type)].letter;
-}
-
-/*
-static boolean includeTag (const tagType type, const boolean isFileScope)
-{
- boolean result;
- if (isFileScope && ! Option.include.fileScope)
- result = FALSE;
- else if (isLanguage (Lang_java))
- result = JavaKinds [javaTagKind (type)].enabled;
- else
- result = CKinds [cTagKind (type)].enabled;
- return result;
-}
-*/
-
-static tagType declToTagType (const declType declaration)
-{
- tagType type = TAG_UNDEFINED;
-
- switch (declaration)
- {
- case DECL_CLASS: type = TAG_CLASS; break;
- case DECL_ENUM: type = TAG_ENUM; break;
- case DECL_FUNCTION: type = TAG_FUNCTION; break;
- case DECL_INTERFACE: type = TAG_INTERFACE; break;
- case DECL_NAMESPACE: type = TAG_NAMESPACE; break;
- case DECL_STRUCT: type = TAG_STRUCT; break;
- case DECL_UNION: type = TAG_UNION; break;
-
- default: Assert ("Unexpected declaration" == NULL); break;
- }
- return type;
-}
-
-static const char* accessField (const statementInfo *const st)
-{
- const char* result = NULL;
- if (st->scope == SCOPE_FRIEND)
- result = "friend";
- else if (st->member.access != ACCESS_UNDEFINED)
- result = accessString (st->member.access);
- return result;
-}
-
-static void addOtherFields (tagEntryInfo* const tag, const tagType type,
- const statementInfo *const st, vString *const scope)
-{
- /* For selected tag types, append an extension flag designating the
- * parent object in which the tag is defined.
- */
- switch (type)
- {
- default: break;
-
- case TAG_CLASS:
- case TAG_ENUM:
- case TAG_ENUMERATOR:
- case TAG_FIELD:
- case TAG_FUNCTION:
- case TAG_INTERFACE:
- case TAG_MEMBER:
- case TAG_METHOD:
- case TAG_PROTOTYPE:
- 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)
- {
-
- tag->extensionFields.inheritance =
- vStringValue (st->parentClasses);
- }
- tag->extensionFields.implementation =
- implementationString (st->implementation);
- if (isMember (st))
- {
- tag->extensionFields.access = accessField (st);
- }
- break;
- }
-
- if ((TAG_FIELD == tag->type) || (TAG_MEMBER == tag->type) ||
- (TAG_EXTERN_VAR == tag->type) || (TAG_TYPEDEF == tag->type) ||
- (TAG_VARIABLE == tag->type) || (TAG_METHOD == tag->type) ||
- (TAG_PROTOTYPE == tag->type) || (TAG_FUNCTION == tag->type))
- {
- if (((TOKEN_NAME == st->firstToken->type) || ((TOKEN_KEYWORD == st->firstToken->type)
- && isBaseDataType(st->firstToken->name->buffer)))
- && (0 != strcmp(vStringValue(st->firstToken->name), tag->name)))
- tag->extensionFields.varType = vStringValue(st->firstToken->name);
- }
-}
-
-static void addContextSeparator (vString *const scope)
-{
- vStringCatS (scope, "::");
-}
-
-static void findScopeHierarchy (vString *const string,
- const statementInfo *const st)
-{
- const char* const anon = "<anonymous>";
- boolean nonAnonPresent = FALSE;
-
- vStringClear (string);
- if (isType (st->context, TOKEN_NAME))
- {
- vStringCopy (string, st->context->name);
- nonAnonPresent = TRUE;
- }
- if (st->parent != NULL)
- {
- vString *temp = vStringNew ();
- const statementInfo *s;
-
- for (s = st->parent ; s != NULL ; s = s->parent)
- {
- if (isContextualStatement (s))
- {
- vStringCopy (temp, string);
- vStringClear (string);
- if (isType (s->blockName, TOKEN_NAME))
- {
- if (isType (s->context, TOKEN_NAME) &&
- vStringLength (s->context->name) > 0)
- {
- vStringCat (string, s->context->name);
- addContextSeparator (string);
- }
- vStringCat (string, s->blockName->name);
- nonAnonPresent = TRUE;
- }
- else
- vStringCopyS (string, anon);
- if (vStringLength (temp) > 0)
- addContextSeparator (string);
- vStringCat (string, temp);
- }
- }
- vStringDelete (temp);
-
- if (! nonAnonPresent)
- vStringClear (string);
- }
-}
-
-static void makeExtraTagEntry (const tagType type, tagEntryInfo *const e,
- vString *const scope)
-{
- if (0 &&
- scope != NULL && vStringLength (scope) > 0)
- {
- vString *const scopedName = vStringNew ();
-
- if (type != TAG_ENUMERATOR)
- vStringCopy (scopedName, scope);
- else
- {
- /* remove last component (i.e. enumeration name) from scope */
- const char* const sc = vStringValue (scope);
- const char* colon = strrchr (sc, ':');
- if (colon != NULL)
- {
- while (*colon == ':' && colon > sc)
- --colon;
- vStringNCopy (scopedName, scope, colon + 1 - sc);
- }
- }
- if (vStringLength (scopedName) > 0)
- {
- addContextSeparator (scopedName);
- vStringCatS (scopedName, e->name);
- e->name = vStringValue (scopedName);
- makeTagEntry (e);
- }
- vStringDelete (scopedName);
- }
-}
-
-static void makeTag (const tokenInfo *const token,
- const statementInfo *const st,
- boolean isFileScope, const tagType type)
-{
-#ifdef DEBUG_C
- printToken(token);
- fprintf(stderr, "<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>\n");
- printStatement(st);
-#endif
- /* Nothing is really of file scope when it appears in a header file.
- */
- isFileScope = (boolean) (isFileScope && ! isHeaderFile ());
-
- if (isType (token, TOKEN_NAME) && vStringLength (token->name) > 0 /* &&
- includeTag (type, isFileScope) */)
- {
- vString *scope = vStringNew ();
- tagEntryInfo e;
-
- initTagEntry (&e, vStringValue (token->name));
-
- e.lineNumber = token->lineNumber;
- e.filePosition = token->filePosition;
- e.isFileScope = isFileScope;
- e.kindName = tagName (type);
- e.kind = tagLetter (type);
- e.type = type;
-
- findScopeHierarchy (scope, st);
- addOtherFields (&e, type, st, scope);
-
-#ifdef DEBUG_C
- printTagEntry(&e);
-#endif
- makeTagEntry (&e);
- if (NULL != TagEntryFunction)
- makeExtraTagEntry (type, &e, scope);
- vStringDelete (scope);
- if (NULL != e.extensionFields.arglist)
- free((char *) e.extensionFields.arglist);
- }
-}
-
-static boolean isValidTypeSpecifier (const declType declaration)
-{
- boolean result;
- switch (declaration)
- {
- case DECL_BASE:
- case DECL_CLASS:
- case DECL_ENUM:
- case DECL_STRUCT:
- case DECL_UNION:
- result = TRUE;
- break;
-
- default:
- result = FALSE;
- break;
- }
- return result;
-}
-
-static void qualifyEnumeratorTag (const statementInfo *const st,
- const tokenInfo *const nameToken)
-{
- if (isType (nameToken, TOKEN_NAME))
- makeTag (nameToken, st, TRUE, TAG_ENUMERATOR);
-}
-
-static void qualifyFunctionTag (const statementInfo *const st,
- const tokenInfo *const nameToken)
-{
- if (isType (nameToken, TOKEN_NAME))
- {
- const tagType type = TAG_FUNCTION;
- const boolean isFileScope =
- (boolean) (st->member.access == ACCESS_PRIVATE ||
- (!isMember (st) && st->scope == SCOPE_STATIC));
-
- makeTag (nameToken, st, isFileScope, type);
- }
-}
-
-static void qualifyFunctionDeclTag (const statementInfo *const st,
- const tokenInfo *const nameToken)
-{
- if (! isType (nameToken, TOKEN_NAME))
- ;
- else if (st->scope == SCOPE_TYPEDEF)
- makeTag (nameToken, st, TRUE, TAG_TYPEDEF);
- else if (isValidTypeSpecifier (st->declaration))
- makeTag (nameToken, st, TRUE, TAG_PROTOTYPE);
-}
-
-static void qualifyCompoundTag (const statementInfo *const st,
- const tokenInfo *const nameToken)
-{
- if (isType (nameToken, TOKEN_NAME))
- {
- const tagType type = declToTagType (st->declaration);
-
- if (type != TAG_UNDEFINED)
- makeTag (nameToken, st, TRUE, type);
- }
-}
-
-static void qualifyBlockTag (statementInfo *const st,
- const tokenInfo *const nameToken)
-{
- switch (st->declaration)
- {
- case DECL_CLASS:
- case DECL_ENUM:
- case DECL_INTERFACE:
- case DECL_NAMESPACE:
- case DECL_STRUCT:
- case DECL_UNION:
- qualifyCompoundTag (st, nameToken);
- break;
- default: break;
- }
-}
-
-static void qualifyVariableTag (const statementInfo *const st,
- const tokenInfo *const nameToken)
-{
- /* We have to watch that we do not interpret a declaration of the
- * form "struct tag;" as a variable definition. In such a case, the
- * token preceding the name will be a keyword.
- */
- 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_PACKAGE)
- makeTag (nameToken, st, FALSE, TAG_PACKAGE);
- else if (isValidTypeSpecifier (st->declaration))
- {
- if (isMember (st))
- {
- if (st->scope == SCOPE_GLOBAL || st->scope == SCOPE_STATIC)
- makeTag (nameToken, st, TRUE, TAG_MEMBER);
- }
- else
- {
- if (st->scope == SCOPE_EXTERN || ! st->haveQualifyingName)
- makeTag (nameToken, st, FALSE, TAG_EXTERN_VAR);
- else
- makeTag (nameToken, st, (boolean) (st->scope == SCOPE_STATIC),
- TAG_VARIABLE);
- }
- }
-}
-
-/*
-* Parsing functions
-*/
-
-/* Skip to the next non-white character.
- */
-static int skipToNonWhite (void)
-{
- int c;
-
- do
- c = cppGetc ();
- while (isspace (c));
-
- return c;
-}
-
-/* Skips to the next brace in column 1. This is intended for cases where
- * preprocessor constructs result in unbalanced braces.
- */
-static void skipToFormattedBraceMatch (void)
-{
- int c, next;
-
- c = cppGetc ();
- next = cppGetc ();
- while (c != EOF && (c != '\n' || next != '}'))
- {
- c = next;
- next = cppGetc ();
- }
-}
-
-/* Skip to the matching character indicated by the pair string. If skipping
- * to a matching brace and any brace is found within a different level of a
- * #if conditional statement while brace formatting is in effect, we skip to
- * the brace matched by its formatting. It is assumed that we have already
- * read the character which starts the group (i.e. the first character of
- * "pair").
- */
-static void skipToMatch (const char *const pair)
-{
- const boolean braceMatching = (boolean) (strcmp ("{}", pair) == 0);
- const boolean braceFormatting = (boolean) (isBraceFormat () && braceMatching);
- const unsigned int initialLevel = getDirectiveNestLevel ();
- const int begin = pair [0], end = pair [1];
- const unsigned long inputLineNumber = getInputLineNumber ();
- int matchLevel = 1;
- int c = '\0';
- while (matchLevel > 0 && (c = cppGetc ()) != EOF)
- {
- if (c == begin)
- {
- ++matchLevel;
- if (braceFormatting && getDirectiveNestLevel () != initialLevel)
- {
- skipToFormattedBraceMatch ();
- break;
- }
- }
- else if (c == end)
- {
- --matchLevel;
- if (braceFormatting && getDirectiveNestLevel () != initialLevel)
- {
- skipToFormattedBraceMatch ();
- break;
- }
- }
- }
- if (c == EOF)
- {
- verbose ("%s: failed to find match for '%c' at line %lu\n", getInputFileName (), begin, inputLineNumber);
- if (braceMatching)
- longjmp (Exception, (int) ExceptionBraceFormattingError);
- else
- longjmp (Exception, (int) ExceptionFormattingError);
- }
-}
-
-static void skipParens (void)
-{
- const int c = skipToNonWhite ();
-
- if (c == '(')
- skipToMatch ("()");
- else
- cppUngetc (c);
-}
-
-static void skipBraces (void)
-{
- const int c = skipToNonWhite ();
-
- if (c == '{')
- skipToMatch ("{}");
- else
- cppUngetc (c);
-}
-
-static keywordId analyzeKeyword (const char *const name)
-{
- const keywordId id = (keywordId) lookupKeyword (name, getSourceLanguage ());
- return id;
-}
-
-static void analyzeIdentifier (tokenInfo *const token)
-{
- char *const name = vStringValue (token->name);
- const char *replacement = NULL;
- boolean parensToo = FALSE;
-
- if (! isIgnoreToken (name, &parensToo, &replacement))
- {
- if (replacement != NULL)
- token->keyword = analyzeKeyword (replacement);
- else
- token->keyword = analyzeKeyword (vStringValue (token->name));
-
- if (token->keyword == KEYWORD_NONE)
- token->type = TOKEN_NAME;
- else
- token->type = TOKEN_KEYWORD;
- }
- else
- {
- initToken (token);
- if (parensToo)
- {
- int c = skipToNonWhite ();
-
- if (c == '(')
- skipToMatch ("()");
- }
- }
-}
-
-static void readIdentifier (tokenInfo *const token, const int firstChar)
-{
- vString *const name = token->name;
- int c = firstChar;
-
- initToken (token);
-
- do
- {
- vStringPut (name, c);
- c = cppGetc ();
- } while (isident (c));
- vStringTerminate (name);
- cppUngetc (c); /* unget non-identifier character */
-
- analyzeIdentifier (token);
-}
-
-static void readPackageName (tokenInfo *const token, const int firstChar)
-{
- vString *const name = token->name;
- int c = firstChar;
-
- initToken (token);
-
- while (isident (c) || c == '.')
- {
- vStringPut (name, c);
- c = cppGetc ();
- }
- vStringTerminate (name);
- cppUngetc (c); /* unget non-package character */
-}
-
-static void readPackage (statementInfo *const st)
-{
- tokenInfo *const token = activeToken (st);
- Assert (isType (token, TOKEN_KEYWORD));
- readPackageName (token, skipToNonWhite ());
- token->type = TOKEN_NAME;
- st->declaration = DECL_PACKAGE;
- st->gotName = TRUE;
- st->haveQualifyingName = TRUE;
-}
-
-static void processName (statementInfo *const st)
-{
- Assert (isType (activeToken (st), TOKEN_NAME));
- if (st->gotName && st->declaration == DECL_NONE)
- st->declaration = DECL_BASE;
- st->gotName = TRUE;
- st->haveQualifyingName = TRUE;
-}
-
-static void readOperator (statementInfo *const st)
-{
- const char *const acceptable = "+-*/%^&|~!=<>,[]";
- const tokenInfo* const prev = prevToken (st,1);
- tokenInfo *const token = activeToken (st);
- vString *const name = token->name;
- int c = skipToNonWhite ();
-
- /* When we arrive here, we have the keyword "operator" in 'name'.
- */
- if (isType (prev, TOKEN_KEYWORD) && (prev->keyword == KEYWORD_ENUM ||
- prev->keyword == KEYWORD_STRUCT || prev->keyword == KEYWORD_UNION))
- ; /* ignore "operator" keyword if preceded by these keywords */
- else if (c == '(')
- {
- /* Verify whether this is a valid function call (i.e. "()") operator.
- */
- if (cppGetc () == ')')
- {
- vStringPut (name, ' '); /* always separate operator from keyword */
- c = skipToNonWhite ();
- if (c == '(')
- vStringCatS (name, "()");
- }
- else
- {
- skipToMatch ("()");
- c = cppGetc ();
- }
- }
- else if (isident1 (c))
- {
- /* Handle "new" and "delete" operators, and conversion functions
- * (per 13.3.1.1.2 [2] of the C++ spec).
- */
- boolean whiteSpace = TRUE; /* default causes insertion of space */
- do
- {
- if (isspace (c))
- whiteSpace = TRUE;
- else
- {
- if (whiteSpace)
- {
- vStringPut (name, ' ');
- whiteSpace = FALSE;
- }
- vStringPut (name, c);
- }
- c = cppGetc ();
- } while (! isOneOf (c, "(;") && c != EOF);
- vStringTerminate (name);
- }
- else if (isOneOf (c, acceptable))
- {
- vStringPut (name, ' '); /* always separate operator from keyword */
- do
- {
- vStringPut (name, c);
- c = cppGetc ();
- } while (isOneOf (c, acceptable));
- vStringTerminate (name);
- }
-
- cppUngetc (c);
-
- token->type = TOKEN_NAME;
- token->keyword = KEYWORD_NONE;
- processName (st);
-}
-
-static void copyToken (tokenInfo *const dest, const tokenInfo *const src)
-{
- dest->type = src->type;
- dest->keyword = src->keyword;
- dest->filePosition = src->filePosition;
- dest->lineNumber = src->lineNumber;
- vStringCopy (dest->name, src->name);
-}
-
-static void setAccess (statementInfo *const st, const accessType access)
-{
- if (isMember (st))
- {
- int c = skipToNonWhite ();
-
- if (c == ':')
- reinitStatement (st, FALSE);
- else
- cppUngetc (c);
-
- st->member.accessDefault = access;
- st->member.access = access;
- }
-}
-
-static void discardTypeList (tokenInfo *const token)
-{
- int c = skipToNonWhite ();
- while (isident1 (c))
- {
- readIdentifier (token, c);
- c = skipToNonWhite ();
- if (c == '.' || c == ',')
- c = skipToNonWhite ();
- }
- cppUngetc (c);
-}
-
-static void addParentClass (statementInfo *const st, tokenInfo *const token)
-{
- if (vStringLength (token->name) > 0 &&
- vStringLength (st->parentClasses) > 0)
- {
- vStringPut (st->parentClasses, ',');
- }
- vStringCat (st->parentClasses, token->name);
-}
-
-static void readParents (statementInfo *const st, const int qualifier)
-{
- tokenInfo *const token = newToken ();
- tokenInfo *const parent = newToken ();
- int c;
-
- do
- {
- c = skipToNonWhite ();
- if (isident1 (c))
- {
- readIdentifier (token, c);
- if (isType (token, TOKEN_NAME))
- vStringCat (parent->name, token->name);
- else
- {
- addParentClass (st, parent);
- initToken (parent);
- }
- }
- else if (c == qualifier)
- vStringPut (parent->name, c);
- else if (c == '<')
- skipToMatch ("<>");
- else if (isType (token, TOKEN_NAME))
- {
- addParentClass (st, parent);
- initToken (parent);
- }
- } while (c != '{' && c != EOF);
- cppUngetc (c);
- deleteToken (parent);
- deleteToken (token);
-}
-
-static void processToken (tokenInfo *const token, statementInfo *const st)
-{
- switch (token->keyword) /* is it a reserved word? */
- {
- default: break;
-
- case KEYWORD_NONE: processName (st); break;
- case KEYWORD_ABSTRACT: st->implementation = IMP_ABSTRACT; break;
- case KEYWORD_ATTRIBUTE: skipParens (); initToken (token); break;
- case KEYWORD_CATCH: skipParens (); skipBraces (); break;
- 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_DOUBLE: st->declaration = DECL_BASE; break;
- case KEYWORD_ENUM: st->declaration = DECL_ENUM; break;
- case KEYWORD_EXTENDS: readParents (st, '.');
- setToken (st, TOKEN_NONE); break;
- case KEYWORD_FLOAT: st->declaration = DECL_BASE; break;
- case KEYWORD_FRIEND: st->scope = SCOPE_FRIEND; break;
- case KEYWORD_IMPLEMENTS:readParents (st, '.');
- setToken (st, TOKEN_NONE); break;
- case KEYWORD_IMPORT: st->declaration = DECL_IGNORE; break;
- case KEYWORD_INT: 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_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;
- case KEYWORD_SHORT: st->declaration = DECL_BASE; break;
- case KEYWORD_SIGNED: st->declaration = DECL_BASE; break;
- case KEYWORD_STRUCT: st->declaration = DECL_STRUCT; break;
- case KEYWORD_THROWS: discardTypeList (token); break;
- case KEYWORD_TYPEDEF: st->scope = SCOPE_TYPEDEF; break;
- case KEYWORD_UNION: st->declaration = DECL_UNION; break;
- case KEYWORD_UNSIGNED: st->declaration = DECL_BASE; break;
- case KEYWORD_USING: st->declaration = DECL_IGNORE; break;
- case KEYWORD_VOID: st->declaration = DECL_BASE; break;
- case KEYWORD_VOLATILE: st->declaration = DECL_BASE; break;
- case KEYWORD_VIRTUAL: st->implementation = IMP_VIRTUAL; break;
-
- case KEYWORD_EXTERN:
- st->scope = SCOPE_EXTERN;
- st->declaration = DECL_BASE;
- break;
-
- case KEYWORD_STATIC:
- st->scope = SCOPE_STATIC;
- st->declaration = DECL_BASE;
- break;
- }
-}
-
-/*
-* Parenthesis handling functions
-*/
-
-static void restartStatement (statementInfo *const st)
-{
- tokenInfo *const save = newToken ();
- tokenInfo *token = activeToken (st);
-
- copyToken (save, token);
- reinitStatement (st, FALSE);
- token = activeToken (st);
- copyToken (token, save);
- deleteToken (save);
- processToken (token, st);
-}
-
-/* Skips over a the mem-initializer-list of a ctor-initializer, defined as:
- *
- * mem-initializer-list:
- * mem-initializer, mem-initializer-list
- *
- * mem-initializer:
- * [::] [nested-name-spec] class-name (...)
- * identifier
- */
-static void skipMemIntializerList (tokenInfo *const token)
-{
- int c;
-
- do
- {
- c = skipToNonWhite ();
- while (isident1 (c) || c == ':')
- {
- if (c != ':')
- readIdentifier (token, c);
- c = skipToNonWhite ();
- }
- if (c == '<')
- {
- skipToMatch ("<>");
- c = skipToNonWhite ();
- }
- if (c == '(')
- {
- skipToMatch ("()");
- c = skipToNonWhite ();
- }
- } while (c == ',');
- cppUngetc (c);
-}
-
-static void skipMacro (statementInfo *const st)
-{
- tokenInfo *const prev2 = prevToken (st, 2);
-
- if (isType (prev2, TOKEN_NAME))
- retardToken (st);
- skipToMatch ("()");
-}
-
-/* Skips over characters following the parameter list. This will be either
- * non-ANSI style function declarations or C++ stuff. Our choices:
- *
- * C (K&R):
- * int func ();
- * int func (one, two) int one; float two; {...}
- * C (ANSI):
- * int func (int one, float two);
- * int func (int one, float two) {...}
- * C++:
- * int foo (...) [const|volatile] [throw (...)];
- * int foo (...) [const|volatile] [throw (...)] [ctor-initializer] {...}
- * int foo (...) [const|volatile] [throw (...)] try [ctor-initializer] {...}
- * catch (...) {...}
- */
-static boolean skipPostArgumentStuff (statementInfo *const st,
- parenInfo *const info)
-{
- tokenInfo *const token = activeToken (st);
- unsigned int parameters = info->parameterCount;
- unsigned int elementCount = 0;
- boolean restart = FALSE;
- boolean end = FALSE;
- int c = skipToNonWhite ();
-
- do
- {
- switch (c)
- {
- case ')': break;
- case ':': skipMemIntializerList (token);break; /* ctor-initializer */
- case '[': skipToMatch ("[]"); break;
- case '=': cppUngetc (c); end = TRUE; break;
- case '{': cppUngetc (c); end = TRUE; break;
- case '}': cppUngetc (c); end = TRUE; break;
-
- case '(':
- if (elementCount > 0)
- ++elementCount;
- skipToMatch ("()");
- break;
-
- case ';':
- if (parameters == 0 || elementCount < 2)
- {
- cppUngetc (c);
- end = TRUE;
- }
- else if (--parameters == 0)
- end = TRUE;
- break;
-
- default:
- if (isident1 (c))
- {
- readIdentifier (token, c);
- switch (token->keyword)
- {
- case KEYWORD_ATTRIBUTE: skipParens (); break;
- case KEYWORD_THROW: skipParens (); break;
- case KEYWORD_CONST: break;
- case KEYWORD_TRY: break;
- case KEYWORD_VOLATILE: break;
- case KEYWORD_WCHAR_T: st->declaration = DECL_BASE; break;
-
- case KEYWORD_CATCH: case KEYWORD_CLASS:
- case KEYWORD_EXPLICIT: case KEYWORD_EXTERN:
- case KEYWORD_FRIEND: case KEYWORD_INLINE:
- case KEYWORD_MUTABLE: case KEYWORD_NAMESPACE:
- case KEYWORD_NEW: case KEYWORD_OPERATOR:
- case KEYWORD_OVERLOAD: case KEYWORD_PRIVATE:
- case KEYWORD_PROTECTED: case KEYWORD_PUBLIC:
- case KEYWORD_STATIC: case KEYWORD_TEMPLATE:
- case KEYWORD_TYPEDEF: case KEYWORD_TYPENAME:
- case KEYWORD_USING: case KEYWORD_VIRTUAL:
- /* Never allowed within parameter declarations.
- */
- restart = TRUE;
- end = TRUE;
- break;
-
- default:
- if (isType (token, TOKEN_NONE))
- ;
- else if (info->isKnrParamList && info->parameterCount > 0)
- ++elementCount;
- else
- {
- /* If we encounter any other identifier immediately
- * following an empty parameter list, this is almost
- * certainly one of those Microsoft macro "thingies"
- * that the automatic source code generation sticks
- * in. Terminate the current statement.
- */
- restart = TRUE;
- end = TRUE;
- }
- break;
- }
- }
- }
- if (! end)
- {
- c = skipToNonWhite ();
- if (c == EOF)
- end = TRUE;
- }
- } while (! end);
-
- if (restart)
- restartStatement (st);
- else
- setToken (st, TOKEN_NONE);
- return (boolean) (c != EOF);
-}
-
-static void analyzePostParens (statementInfo *const st, parenInfo *const info)
-{
- const unsigned long inputLineNumber = getInputLineNumber ();
- int c = skipToNonWhite ();
-
- cppUngetc (c);
- if (isOneOf (c, "{;,="))
- ;
- else
- {
- if (! skipPostArgumentStuff (st, info))
- {
- verbose (
- "%s: confusing argument declarations beginning at line %lu\n",
- getInputFileName (), inputLineNumber);
- longjmp (Exception, (int) ExceptionFormattingError);
- }
- }
-}
-
-static int parseParens (statementInfo *const st, parenInfo *const info)
-{
- tokenInfo *const token = activeToken (st);
- unsigned int identifierCount = 0;
- unsigned int depth = 1;
- boolean firstChar = TRUE;
- int nextChar = '\0';
-
- info->parameterCount = 1;
- do
- {
- int c = skipToNonWhite ();
- switch (c)
- {
- case '&':
- case '*':
- info->isPointer = TRUE;
- info->isKnrParamList = FALSE;
- if (identifierCount == 0)
- info->isParamList = FALSE;
- initToken (token);
- break;
-
- case ':':
- info->isKnrParamList = FALSE;
- break;
-
- case '.':
- info->isNameCandidate = FALSE;
- info->isKnrParamList = FALSE;
- break;
-
- case ',':
- info->isNameCandidate = FALSE;
- if (info->isKnrParamList)
- {
- ++info->parameterCount;
- identifierCount = 0;
- }
- break;
-
- case '=':
- info->isKnrParamList = FALSE;
- info->isNameCandidate = FALSE;
- if (firstChar)
- {
- info->isParamList = FALSE;
- skipMacro (st);
- depth = 0;
- }
- break;
-
- case '[':
- info->isKnrParamList = FALSE;
- skipToMatch ("[]");
- break;
-
- case '<':
- info->isKnrParamList = FALSE;
- skipToMatch ("<>");
- break;
-
- case ')':
- if (firstChar)
- info->parameterCount = 0;
- --depth;
- break;
-
- case '(':
- info->isKnrParamList = FALSE;
- if (firstChar)
- {
- info->isNameCandidate = FALSE;
- cppUngetc (c);
- skipMacro (st);
- depth = 0;
- }
- else if (isType (token, TOKEN_PAREN_NAME))
- {
- c = skipToNonWhite ();
- if (c == '*') /* check for function pointer */
- {
- skipToMatch ("()");
- c = skipToNonWhite ();
- if (c == '(')
- skipToMatch ("()");
- }
- else
- {
- cppUngetc (c);
- cppUngetc ('(');
- info->nestedArgs = TRUE;
- }
- }
- else
- ++depth;
- break;
-
- default:
- if (isident1 (c))
- {
- if (++identifierCount > 1)
- info->isKnrParamList = FALSE;
- readIdentifier (token, c);
- if (isType (token, TOKEN_NAME) && info->isNameCandidate)
- token->type = TOKEN_PAREN_NAME;
- else if (isType (token, TOKEN_KEYWORD))
- {
- info->isKnrParamList = FALSE;
- info->isNameCandidate = FALSE;
- }
- }
- else
- {
- info->isParamList = FALSE;
- info->isKnrParamList = FALSE;
- info->isNameCandidate = FALSE;
- info->invalidContents = TRUE;
- }
- break;
- }
- firstChar = FALSE;
- } while (! info->nestedArgs && depth > 0 &&
- (info->isKnrParamList || info->isNameCandidate));
-
- if (! info->nestedArgs) while (depth > 0)
- {
- skipToMatch ("()");
- --depth;
- }
- if (st->argEndPosition == 0)
- st->argEndPosition = ftell(File.fp);
-
- if (! info->isNameCandidate)
- initToken (token);
-
- return nextChar;
-}
-
-static void initParenInfo (parenInfo *const info)
-{
- info->isPointer = FALSE;
- info->isParamList = TRUE;
- info->isKnrParamList = TRUE;
- info->isNameCandidate = TRUE;
- info->invalidContents = FALSE;
- info->nestedArgs = FALSE;
- info->parameterCount = 0;
-}
-
-static void analyzeParens (statementInfo *const st)
-{
- tokenInfo *const prev = prevToken (st, 1);
-
- if (! isType (prev, TOKEN_NONE)) /* in case of ignored enclosing macros */
- {
- tokenInfo *const token = activeToken (st);
- parenInfo info;
- int c;
-
- initParenInfo (&info);
- parseParens (st, &info);
- c = skipToNonWhite ();
- cppUngetc (c);
- if (info.invalidContents)
- reinitStatement (st, FALSE);
- else if (info.isNameCandidate && isType (token, TOKEN_PAREN_NAME) &&
- ! st->gotParenName &&
- (! info.isParamList || ! st->haveQualifyingName ||
- c == '(' ||
- (c == '=' && st->implementation != IMP_VIRTUAL) ||
- (st->declaration == DECL_NONE && isOneOf (c, ",;"))))
- {
- token->type = TOKEN_NAME;
- processName (st);
- st->gotParenName = TRUE;
- if (! (c == '(' && info.nestedArgs))
- st->isPointer = info.isPointer;
- }
- else if (! st->gotArgs && info.isParamList)
- {
- st->gotArgs = TRUE;
- setToken (st, TOKEN_ARGS);
- advanceToken (st);
- analyzePostParens (st, &info);
- }
- else
- setToken (st, TOKEN_NONE);
- }
-}
-
-/*
-* Token parsing functions
-*/
-
-static void addContext (statementInfo *const st, const tokenInfo* const token)
-{
- if (isType (token, TOKEN_NAME))
- {
- if (vStringLength (st->context->name) > 0)
- {
- vStringCatS (st->context->name, "::");
- }
- vStringCat (st->context->name, token->name);
- st->context->type = TOKEN_NAME;
- }
-}
-
-static void processColon (statementInfo *const st)
-{
- const int c = skipToNonWhite ();
- const boolean doubleColon = (boolean) (c == ':');
-
- if (doubleColon)
- {
- setToken (st, TOKEN_DOUBLE_COLON);
- st->haveQualifyingName = FALSE;
- }
- else
- {
- cppUngetc (c);
- if (st->declaration == DECL_CLASS || st->declaration == DECL_STRUCT)
- {
- readParents (st, ':');
- }
- }
-}
-
-/* Skips over any initializing value which may follow an '=' character in a
- * variable definition.
- */
-static int skipInitializer (statementInfo *const st)
-{
- boolean done = FALSE;
- int c;
-
- while (! done)
- {
- c = skipToNonWhite ();
-
- if (c == EOF)
- longjmp (Exception, (int) ExceptionFormattingError);
- else switch (c)
- {
- case ',':
- case ';': done = TRUE; break;
-
- case '0':
- if (st->implementation == IMP_VIRTUAL)
- st->implementation = IMP_PURE_VIRTUAL;
- break;
-
- case '[': skipToMatch ("[]"); break;
- case '(': skipToMatch ("()"); break;
- case '{': skipToMatch ("{}"); break;
-
- case '}':
- if (insideEnumBody (st))
- done = TRUE;
- else if (! isBraceFormat ())
- {
- verbose ("%s: unexpected closing brace at line %lu\n",
- getInputFileName (), getInputLineNumber ());
- longjmp (Exception, (int) ExceptionBraceFormattingError);
- }
- break;
-
- default: break;
- }
- }
- return c;
-}
-
-static void processInitializer (statementInfo *const st)
-{
- const boolean inEnumBody = insideEnumBody (st);
- const int c = skipInitializer (st);
-
- if (c == ';')
- setToken (st, TOKEN_SEMICOLON);
- else if (c == ',')
- setToken (st, TOKEN_COMMA);
- else if ('}' && inEnumBody)
- {
- cppUngetc (c);
- setToken (st, TOKEN_COMMA);
- }
- if (st->scope == SCOPE_EXTERN)
- st->scope = SCOPE_GLOBAL;
-}
-
-static void parseIdentifier (statementInfo *const st, const int c)
-{
- tokenInfo *const token = activeToken (st);
-
- readIdentifier (token, c);
- if (! isType (token, TOKEN_NONE))
- processToken (token, st);
-}
-
-static void parseGeneralToken (statementInfo *const st, const int c)
-{
- const tokenInfo *const prev = prevToken (st, 1);
-
- if (isident1(c))
- {
- parseIdentifier (st, c);
- if (isType (st->context, TOKEN_NAME) &&
- isType (activeToken (st), TOKEN_NAME) && isType (prev, TOKEN_NAME))
- {
- initToken (st->context);
- }
- }
- else if (isExternCDecl (st, c))
- {
- st->declaration = DECL_NOMANGLE;
- st->scope = SCOPE_GLOBAL;
- }
-}
-
-/* Reads characters from the pre-processor and assembles tokens, setting
- * the current statement state.
- */
-static void nextToken (statementInfo *const st)
-{
- tokenInfo *token = activeToken (st);
- do
- {
-
- int c = skipToNonWhite ();
-
- switch (c)
- {
- case EOF: longjmp (Exception, (int) ExceptionEOF); break;
- case '(': analyzeParens (st); token = activeToken (st); break;
- case '*': st->haveQualifyingName = FALSE; break;
- case ',': setToken (st, TOKEN_COMMA); break;
- case ':': processColon (st); break;
- case ';': setToken (st, TOKEN_SEMICOLON); break;
- case '<': skipToMatch ("<>"); break;
- case '=': processInitializer (st); break;
- case '[': skipToMatch ("[]"); break;
- case '{': setToken (st, TOKEN_BRACE_OPEN); break;
- case '}': setToken (st, TOKEN_BRACE_CLOSE); break;
- default: parseGeneralToken (st, c); break;
- }
- } 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) || ((TOKEN_KEYWORD == token->type)
- && (isBaseDataType(token->name->buffer))))
- copyToken(st->firstToken, token);
- }
-}
-
-/*
-* Scanning support functions
-*/
-
-static statementInfo *CurrentStatement = NULL;
-
-static statementInfo *newStatement (statementInfo *const parent)
-{
- statementInfo *const st = xMalloc (1, statementInfo);
- unsigned int i;
-
- for (i = 0 ; i < (unsigned int) NumTokens ; ++i)
- st->token [i] = newToken ();
-
- st->context = newToken ();
- st->blockName = newToken ();
- st->parentClasses = vStringNew ();
- st->firstToken = newToken();
-
- initStatement (st, parent);
- CurrentStatement = st;
-
- return st;
-}
-
-static void deleteStatement (void)
-{
- statementInfo *const st = CurrentStatement;
- statementInfo *const parent = st->parent;
- unsigned int i;
-
- for (i = 0 ; i < (unsigned int) NumTokens ; ++i)
- {
- deleteToken (st->token [i]); st->token [i] = NULL;
- }
- deleteToken (st->blockName); st->blockName = NULL;
- deleteToken (st->context); st->context = NULL;
- vStringDelete (st->parentClasses); st->parentClasses = NULL;
- deleteToken(st->firstToken);
- eFree (st);
- CurrentStatement = parent;
-}
-
-static void deleteAllStatements (void)
-{
- while (CurrentStatement != NULL)
- deleteStatement ();
-}
-
-static boolean isStatementEnd (const statementInfo *const st)
-{
- const tokenInfo *const token = activeToken (st);
- boolean isEnd;
-
- if (isType (token, TOKEN_SEMICOLON))
- isEnd = TRUE;
- else if (isType (token, TOKEN_BRACE_CLOSE))
- isEnd = (boolean) ! isContextualStatement (st);
- else
- isEnd = FALSE;
-
- return isEnd;
-}
-
-static void checkStatementEnd (statementInfo *const st)
-{
- const tokenInfo *const token = activeToken (st);
-
- if (isType (token, TOKEN_COMMA))
- reinitStatement (st, TRUE);
- else if (isStatementEnd (st))
- {
- reinitStatement (st, FALSE);
- cppEndStatement ();
- }
- else
- {
- cppBeginStatement ();
- advanceToken (st);
- }
-}
-
-static void nest (statementInfo *const st, const unsigned int nestLevel)
-{
- switch (st->declaration)
- {
- case DECL_CLASS:
- case DECL_ENUM:
- case DECL_INTERFACE:
- case DECL_NAMESPACE:
- case DECL_NOMANGLE:
- case DECL_STRUCT:
- case DECL_UNION:
- createTags (nestLevel, st);
- break;
- default:
- skipToMatch ("{}");
- break;
- }
- advanceToken (st);
- setToken (st, TOKEN_BRACE_CLOSE);
-}
-
-static void tagCheck (statementInfo *const st)
-{
- const tokenInfo *const token = activeToken (st);
- const tokenInfo *const prev = prevToken (st, 1);
- const tokenInfo *const prev2 = prevToken (st, 2);
-
- switch (token->type)
- {
- case TOKEN_NAME:
- if (insideEnumBody (st))
- qualifyEnumeratorTag (st, token);
- break;
-#if 0
- case TOKEN_PACKAGE:
- if (st->haveQualifyingName)
- makeTag (token, st, FALSE, TAG_PACKAGE);
- break;
-#endif
- case TOKEN_BRACE_OPEN:
- if (isType (prev, TOKEN_ARGS))
- {
- if (st->haveQualifyingName)
- {
- st->declaration = DECL_FUNCTION;
- if (isType (prev2, TOKEN_NAME))
- copyToken (st->blockName, prev2);
- qualifyFunctionTag (st, prev2);
- }
- }
- else if (isContextualStatement (st))
- {
- if (isType (prev, TOKEN_NAME))
- copyToken (st->blockName, prev);
- qualifyBlockTag (st, prev);
- }
- break;
-
- case TOKEN_SEMICOLON:
- case TOKEN_COMMA:
- if (insideEnumBody (st))
- ;
- else if (isType (prev, TOKEN_NAME))
- {
- if (isContextualKeyword (prev2))
- st->scope = SCOPE_EXTERN;
- else
- qualifyVariableTag (st, prev);
- }
- else if (isType (prev, TOKEN_ARGS) && isType (prev2, TOKEN_NAME))
- {
- if (st->isPointer)
- qualifyVariableTag (st, prev2);
- else
- qualifyFunctionDeclTag (st, prev2);
- }
- break;
-
- default: break;
- }
-}
-
-/* Parses the current file and decides whether to write out and tags that
- * are discovered.
- */
-static void createTags (const unsigned int nestLevel,
- statementInfo *const parent)
-{
- statementInfo *const st = newStatement (parent);
-
- while (TRUE)
- {
- tokenInfo *token;
-
- nextToken (st);
- token = activeToken (st);
- if (isType (token, TOKEN_BRACE_CLOSE))
- {
- if (nestLevel > 0)
- break;
- else
- {
- verbose ("%s: unexpected closing brace at line %lu\n",
- getInputFileName (), getInputLineNumber ());
- longjmp (Exception, (int) ExceptionBraceFormattingError);
- }
- }
- else if (isType (token, TOKEN_DOUBLE_COLON))
- {
- addContext (st, prevToken (st, 1));
- advanceToken (st);
- }
- else
- {
- tagCheck (st);
- if (isType (token, TOKEN_BRACE_OPEN))
- nest (st, nestLevel + 1);
- checkStatementEnd (st);
- }
- }
- deleteStatement ();
-}
-
-static boolean findDTags (const unsigned int passCount)
-{
- exception_t exception;
- boolean retry;
-
- Assert (passCount < 3);
- cppInit ((boolean) (passCount > 1));
-
- exception = (exception_t) setjmp (Exception);
- retry = FALSE;
- if (exception == ExceptionNone)
- createTags (0, NULL);
- else
- {
- deleteAllStatements ();
- if (exception == ExceptionBraceFormattingError && passCount == 1)
- {
- retry = TRUE;
- verbose ("%s: retrying file with fallback brace matching algorithm\n",
- getInputFileName ());
- }
- }
- cppTerminate ();
- return retry;
-}
-
-static void buildKeywordHash (const langType language, unsigned int idx)
-{
- const size_t count = sizeof (KeywordTable) / sizeof (KeywordTable [0]);
- size_t i;
- for (i = 0 ; i < count ; ++i)
- {
- const keywordDesc* const p = &KeywordTable [i];
- if (p->isValid [idx])
- addKeyword (p->name, language, (int) p->id);
- }
-}
-
-static void initializeDParser (const langType language)
-{
- Lang_d = language;
- buildKeywordHash (language, 17);
-}
-
-
-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 = findDTags;
- def->initialize = initializeDParser;
- return def;
-}
-
-
-/* vi:set tabstop=8 shiftwidth=4: */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Commits
mailing list