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