⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c.c

📁 ultraEdit的Ctag标签工具的实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    { "wchar_t",	KEYWORD_WCHAR_T,	{ 1, 1, 1, 0, 0 } },
    { "while",		KEYWORD_WHILE,		{ 1, 1, 1, 1, 0 } }
};

/*
*   FUNCTION PROTOTYPES
*/
static void createTags (const unsigned int nestLevel, statementInfo *const parent);

/*
*   FUNCTION DEFINITIONS
*/

extern boolean includingDefineTags (void)
{
    return CKinds [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 [] = {
	"?", "local", "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 DEBUG

#define boolString(c)   ((c) ? "TRUE" : "FALSE")

static const char *tokenString (const tokenType type)
{
    static const char *const names [] = {
	"none", "args", "}", "{", "colon", "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", "event", "function", "ignore", "interface",
	"namespace", "no mangle", "package", "program", "struct", "task", "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_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 = (boolean)(st->parent != NULL && 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:
	    if (isLanguage (Lang_java))
		accessDefault = ACCESS_DEFAULT;
	    else
		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->inFunction	= FALSE;
    st->assignment	= FALSE;
    st->notVariable	= FALSE;
    st->implementation	= IMP_DEFAULT;
    st->gotArgs		= FALSE;
    st->gotName		= FALSE;
    st->haveQualifyingName = FALSE;
    st->tokenIndex	= 0;

    if (st->parent != NULL)
    {
	st->inFunction = st->parent->inFunction;
    }

    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;
}

static void initStatement (statementInfo *const st, statementInfo *const parent)
{
    st->parent = parent;
    initMemberInfo (st);
    reinitStatement (st, FALSE);
}

/*
*   Tag generation functions
*/
static cKind cTagKind (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_LOCAL:      result = CK_LOCAL;       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 csharpKind csharpTagKind (const tagType type)
{
    csharpKind result = CSK_UNDEFINED;
    switch (type)
    {
	case TAG_CLASS:      result = CSK_CLASS;           break;
	case TAG_ENUM:       result = CSK_ENUMERATION;     break;
	case TAG_ENUMERATOR: result = CSK_ENUMERATOR;      break;
	case TAG_EVENT:      result = CSK_EVENT;           break;
	case TAG_FIELD:      result = CSK_FIELD ;          break;
	case TAG_INTERFACE:  result = CSK_INTERFACE;       break;
	case TAG_LOCAL:      result = CSK_LOCAL;           break;
	case TAG_METHOD:     result = CSK_METHOD;          break;
	case TAG_NAMESPACE:  result = CSK_NAMESPACE;       break;
	case TAG_PROPERTY:   result = CSK_PROPERTY;        break;
	case TAG_STRUCT:     result = CSK_STRUCT;          break;
	case TAG_TYPEDEF:    result = CSK_TYPEDEF;         break;

	default: Assert ("Bad C# tag type" == NULL); break;
    }
    return result;
}

static javaKind javaTagKind (const tagType type)
{
    javaKind result = JK_UNDEFINED;
    switch (type)
    {
	case TAG_CLASS:     result = JK_CLASS;     break;
	case TAG_FIELD:     result = JK_FIELD;     break;
	case TAG_INTERFACE: result = JK_INTERFACE; break;
	case TAG_LOCAL:     result = JK_LOCAL;     break;
	case TAG_METHOD:    result = JK_METHOD;    break;
	case TAG_PACKAGE:   result = JK_PACKAGE;   break;

	default: Assert ("Bad Java tag type" == NULL); break;
    }
    return result;
}

static veraKind veraTagKind (const tagType type) {
    veraKind result = VK_UNDEFINED;
    switch (type)
    {
	case TAG_CLASS:      result = VK_CLASS;           break;
	case TAG_ENUM:       result = VK_ENUMERATION;     break;
	case TAG_ENUMERATOR: result = VK_ENUMERATOR;      break;
	case TAG_FUNCTION:   result = VK_FUNCTION;        break;
	case TAG_LOCAL:      result = VK_LOCAL;           break;
	case TAG_MEMBER:     result = VK_MEMBER;          break;
	case TAG_PROGRAM:    result = VK_PROGRAM;         break;
	case TAG_PROTOTYPE:  result = VK_PROTOTYPE;       break;
	case TAG_TASK:       result = VK_TASK;            break;
	case TAG_TYPEDEF:    result = VK_TYPEDEF;         break;
	case TAG_VARIABLE:   result = VK_VARIABLE;        break;
	case TAG_EXTERN_VAR: result = VK_EXTERN_VARIABLE; break;

	default: Assert ("Bad Vera tag type" == NULL); break;
    }
    return result;
}

static const char *tagName (const tagType type)
{
    const char* result;
    if (isLanguage (Lang_csharp))
	result = CsharpKinds [csharpTagKind (type)].name;
    else if (isLanguage (Lang_java))
	result = JavaKinds [javaTagKind (type)].name;
    else if (isLanguage (Lang_vera))
	result = VeraKinds [veraTagKind (type)].name;
    else
	result = CKinds [cTagKind (type)].name;
    return result;
}

static int tagLetter (const tagType type)
{
    int result;
    if (isLanguage (Lang_csharp))
	result = CsharpKinds [csharpTagKind (type)].letter;
    else if (isLanguage (Lang_java))
	result = JavaKinds [javaTagKind (type)].letter;
    else if (isLanguage (Lang_vera))
	result = VeraKinds [veraTagKind (type)].letter;
    else
	result = CKinds [cTagKind (type)].letter;
    return result;
}

static boolean includeTag (const tagType type, const boolean isFileScope)
{
    boolean result;
    if (isFileScope  &&  ! Option.include.fileScope)
	result = FALSE;
    else if (isLanguage (Lang_csharp))
	result = CsharpKinds [csharpTagKind (type)].enabled;
    else if (isLanguage (Lang_java))
	result = JavaKinds [javaTagKind (type)].enabled;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -