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

📄 c.c

📁 ultraEdit的Ctag标签工具的实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 *    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_TRY:			break;

		case KEYWORD_CONST:
		case KEYWORD_VOLATILE:
		    if (vStringLength (Signature) > 0)
		    {
			vStringPut (Signature, ' ');
			vStringCat (Signature, token->name);
		    }
		    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_NEWCOV:
		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 skipJavaThrows (statementInfo *const st)
{
    tokenInfo *const token = activeToken (st);
    int c = skipToNonWhite ();

    if (isident1 (c))
    {
	readIdentifier (token, c);
	if (token->keyword == KEYWORD_THROWS)
	{
	    do
	    {
		c = skipToNonWhite ();
		if (isident1 (c))
		{
		    readIdentifier (token, c);
		    c = skipToNonWhite ();
		}
	    } while (c == '.'  ||  c == ',');
	}
    }
    cppUngetc (c);
    setToken (st, TOKEN_NONE);
}

static void analyzePostParens (statementInfo *const st, parenInfo *const info)
{
    const unsigned long inputLineNumber = getInputLineNumber ();
    int c = skipToNonWhite ();

    cppUngetc (c);
    if (isOneOf (c, "{;,="))
	;
    else if (isLanguage (Lang_java))
	skipJavaThrows (st);
    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';

    CollectingSignature = TRUE;
    vStringClear (Signature);
    vStringPut (Signature, '(');
    info->parameterCount = 1;
    do
    {
	int c = skipToNonWhite ();
	vStringPut (Signature, c);

	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);
		    vStringClear (Signature);
		    skipMacro (st);
		    depth = 0;
		    vStringChop (Signature);
		}
		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))
		    {
			if (token->keyword != KEYWORD_CONST &&
			    token->keyword != KEYWORD_VOLATILE)
			{
			    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 (! info->isNameCandidate)
	initToken (token);

    vStringTerminate (Signature);
    if (info->isKnrParamList)
	vStringClear (Signature);
    CollectingSignature = FALSE;
    return nextChar;
}

static void initParenInfo (parenInfo *const info)
{
    info->isPointer		= FALSE;
    info->isParamList		= TRUE;
    info->isKnrParamList	= isLanguage (Lang_c);
    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 (st->inFunction  &&  ! st->assignment)
	st->notVariable = TRUE;
    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);
	    if (st->scope != SCOPE_TYPEDEF)
		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)
	{
	    if (isLanguage (Lang_c)  ||  isLanguage (Lang_cpp))
		vStringCatS (st->context->name, "::");
	    else if (isLanguage (Lang_java) || isLanguage (Lang_csharp))
		vStringCatS (st->context->name, ".");
	}
	vStringCat (st->context->name, token->name);
	st->context->type = TOKEN_NAME;
    }
}

static boolean inheritingDeclaration (declType decl)
{
    return (boolean) (
	decl == DECL_CLASS ||
	decl == DECL_STRUCT ||
	decl == DECL_INTERFACE);
}

static void processColon (statementInfo *const st)
{
    int c = skipToNonWhite ();
    const boolean doubleColon = (boolean) (c == ':');

    if (doubleColon)
    {
	setToken (st, TOKEN_DOUBLE_COLON);
	st->haveQualifyingName = FALSE;
    }
    else
    {
	cppUngetc (c);
	if ((isLanguage (Lang_cpp) || isLanguage (Lang_csharp))  &&
	    inheritingDeclaration (st->declaration))
	{
	    readParents (st, ':');
	}
	else if (parentDecl (st) == DECL_STRUCT)
	{
	    c = skipToOneOf (",;");
	    if (c == ',')
		setToken (st, TOKEN_COMMA);
	    else if (c == ';')
		setToken (st, TOKEN_SEMICOLON);
	}
	else
	{
	    const tokenInfo *const prev  = prevToken (st, 1);
	    const tokenInfo *const prev2 = prevToken (st, 2);
	    if (prev->keyword == KEYWORD_DEFAULT ||
		prev2->keyword == KEYWORD_CASE ||
		st->parent != NULL)
	    {
		reinitStatement (st, FALSE);
	    }
	}
    }
}

static void processAngleBracket (v

⌨️ 快捷键说明

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