📄 c.c
字号:
* 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 + -