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

📄 c.c

📁 ultraEdit的Ctag标签工具的实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
*   $Id: c.c,v 1.28 2004/02/28 15:37:52 darren Exp $
*
*   Copyright (c) 1996-2003, Darren Hiebert
*
*   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
*   source files.
*/

/*
*   INCLUDE FILES
*/
#include "general.h"	/* must always come first */

#include <string.h>
#include <setjmp.h>

#include "debug.h"
#include "entry.h"
#include "get.h"
#include "keyword.h"
#include "options.h"
#include "parse.h"
#include "read.h"
#include "routines.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)	((st)->parent == NULL ? FALSE : \
			    (boolean) ((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)

#define isHighChar(c)		((unsigned char)(c) >= 0xc0)

/*
*   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 = -1,
    KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT,
    KEYWORD_BOOLEAN, KEYWORD_BYTE, KEYWORD_BAD_STATE, KEYWORD_BAD_TRANS,
    KEYWORD_BIND, KEYWORD_BIND_VAR, KEYWORD_BIT,
    KEYWORD_CASE, KEYWORD_CATCH, KEYWORD_CHAR, KEYWORD_CLASS, KEYWORD_CONST,
    KEYWORD_CONSTRAINT, KEYWORD_COVERAGE_BLOCK, KEYWORD_COVERAGE_DEF,
    KEYWORD_DEFAULT, KEYWORD_DELEGATE, KEYWORD_DO, KEYWORD_DOUBLE,
    KEYWORD_ELSE, KEYWORD_ENUM, KEYWORD_EXPLICIT, KEYWORD_EXTERN,
    KEYWORD_EXTENDS, KEYWORD_EVENT,
    KEYWORD_FINAL, KEYWORD_FLOAT, KEYWORD_FOR, KEYWORD_FRIEND, KEYWORD_FUNCTION,
    KEYWORD_GOTO,
    KEYWORD_IF, KEYWORD_IMPLEMENTS, KEYWORD_IMPORT, KEYWORD_INLINE, KEYWORD_INT,
    KEYWORD_INOUT, KEYWORD_INPUT, KEYWORD_INTEGER, KEYWORD_INTERFACE,
    KEYWORD_INTERNAL,
    KEYWORD_LOCAL, KEYWORD_LONG,
    KEYWORD_M_BAD_STATE, KEYWORD_M_BAD_TRANS, KEYWORD_M_STATE, KEYWORD_M_TRANS,
    KEYWORD_MUTABLE,
    KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NEWCOV, KEYWORD_NATIVE,
    KEYWORD_OPERATOR, KEYWORD_OUTPUT, KEYWORD_OVERLOAD, KEYWORD_OVERRIDE,
    KEYWORD_PACKED, KEYWORD_PORT, KEYWORD_PACKAGE, KEYWORD_PRIVATE,
    KEYWORD_PROGRAM, KEYWORD_PROTECTED, KEYWORD_PUBLIC,
    KEYWORD_REGISTER, KEYWORD_RETURN,
    KEYWORD_SHADOW, KEYWORD_STATE,
    KEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STRING,
    KEYWORD_STRUCT, KEYWORD_SWITCH, KEYWORD_SYNCHRONIZED,
    KEYWORD_TASK, KEYWORD_TEMPLATE, KEYWORD_THIS, KEYWORD_THROW,
    KEYWORD_THROWS, KEYWORD_TRANSIENT, KEYWORD_TRANS, KEYWORD_TRANSITION,
    KEYWORD_TRY, KEYWORD_TYPEDEF, KEYWORD_TYPENAME,
    KEYWORD_UINT, KEYWORD_ULONG, KEYWORD_UNION, KEYWORD_UNSIGNED, KEYWORD_USHORT,
    KEYWORD_USING,
    KEYWORD_VIRTUAL, KEYWORD_VOID, KEYWORD_VOLATILE,
    KEYWORD_WCHAR_T, KEYWORD_WHILE
} 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 [5]; /* 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_COLON,	/* the colon character */
    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_EVENT,
    DECL_FUNCTION,
    DECL_IGNORE,		/* non-taggable "declaration" */
    DECL_INTERFACE,
    DECL_NAMESPACE,
    DECL_NOMANGLE,		/* C++ name demangling block */
    DECL_PACKAGE,
    DECL_PROGRAM,		/* Vera program */
    DECL_STRUCT,
    DECL_TASK,			/* Vera task */
    DECL_UNION,
    DECL_COUNT
} declType;

typedef enum eVisibilityType {
    ACCESS_UNDEFINED,
    ACCESS_LOCAL,
    ACCESS_PRIVATE,
    ACCESS_PROTECTED,
    ACCESS_PUBLIC,
    ACCESS_DEFAULT,		/* Java-specific */
    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? */
    boolean     inFunction;	/* are we inside of a function? */
    boolean	assignment;	/* have we handled an '='? */
    boolean	notVariable;	/* has a variable declaration been disqualified ? */
    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 */
} 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_EVENT,			/* event */
    TAG_FIELD,			/* field (Java) */
    TAG_FUNCTION,		/* function definition */
    TAG_INTERFACE,		/* interface declaration */
    TAG_LOCAL,			/* local variable definition */
    TAG_MEMBER,			/* structure, class or interface member */
    TAG_METHOD,			/* method declaration */
    TAG_NAMESPACE,		/* namespace name */
    TAG_PACKAGE,		/* package name */
    TAG_PROGRAM,		/* program name */
    TAG_PROPERTY,		/* property name */
    TAG_PROTOTYPE,		/* function prototype or declaration */
    TAG_STRUCT,			/* structure name */
    TAG_TASK,			/* task name */
    TAG_TYPEDEF,		/* typedef name */
    TAG_UNION,			/* union name */
    TAG_VARIABLE,		/* variable definition */
    TAG_EXTERN_VAR,		/* external variable declaration */
    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_c;
static langType Lang_cpp;
static langType Lang_csharp;
static langType Lang_java;
static langType Lang_vera;
static vString *Signature;
static boolean CollectingSignature;

/* Used to index into the CKinds table. */
typedef enum {
    CK_UNDEFINED = -1,
    CK_CLASS, CK_DEFINE, CK_ENUMERATOR, CK_FUNCTION,
    CK_ENUMERATION, CK_LOCAL, CK_MEMBER, CK_NAMESPACE, CK_PROTOTYPE,
    CK_STRUCT, CK_TYPEDEF, CK_UNION, CK_VARIABLE,
    CK_EXTERN_VARIABLE
} cKind;

static kindOption CKinds [] = {
    { 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"},
    { FALSE, 'l', "local",      "local variables"},
    { 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"},
};

typedef enum {
    CSK_UNDEFINED = -1,
    CSK_CLASS, CSK_DEFINE, CSK_ENUMERATOR, CSK_EVENT, CSK_FIELD,
    CSK_ENUMERATION, CSK_INTERFACE, CSK_LOCAL, CSK_METHOD,
    CSK_NAMESPACE, CSK_PROPERTY, CSK_STRUCT, CSK_TYPEDEF
} csharpKind;

static kindOption CsharpKinds [] = {
    { TRUE,  'c', "class",      "classes"},
    { TRUE,  'd', "macro",      "macro definitions"},
    { TRUE,  'e', "enumerator", "enumerators (values inside an enumeration)"},
    { TRUE,  'E', "event",      "events"},
    { TRUE,  'f', "field",      "fields"},
    { TRUE,  'g', "enum",       "enumeration names"},
    { TRUE,  'i', "interface",  "interfaces"},
    { FALSE, 'l', "local",      "local variables"},
    { TRUE,  'm', "method",     "methods"},
    { TRUE,  'n', "namespace",  "namespaces"},
    { TRUE,  'p', "property",   "properties"},
    { TRUE,  's', "struct",     "structure names"},
    { TRUE,  't', "typedef",    "typedefs"},
};

/* Used to index into the JavaKinds table. */
typedef enum {
    JK_UNDEFINED = -1,
    JK_CLASS, JK_FIELD, JK_INTERFACE, JK_LOCAL, JK_METHOD,
    JK_PACKAGE, JK_ACCESS, JK_CLASS_PREFIX
} javaKind;

static kindOption JavaKinds [] = {
    { TRUE,  'c', "class",     "classes"},
    { TRUE,  'f', "field",     "fields"},
    { TRUE,  'i', "interface", "interfaces"},
    { FALSE, 'l', "local",     "local variables"},
    { TRUE,  'm', "method",    "methods"},
    { TRUE,  'p', "package",   "packages"},
};

/* Used to index into the VeraKinds table. */
typedef enum {
    VK_UNDEFINED = -1,
    VK_CLASS, VK_DEFINE, VK_ENUMERATOR, VK_FUNCTION,
    VK_ENUMERATION, VK_LOCAL, VK_MEMBER, VK_PROGRAM, VK_PROTOTYPE,
    VK_TASK, VK_TYPEDEF, VK_VARIABLE,
    VK_EXTERN_VARIABLE
} veraKind;

static kindOption VeraKinds [] = {
    { 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"},
    { FALSE, 'l', "local",      "local variables"},
    { TRUE,  'm', "member",     "class, struct, and union members"},
    { TRUE,  'p', "program",    "programs"},
    { FALSE, 'P', "prototype",  "function prototypes"},
    { TRUE,  't', "task",       "tasks"},
    { TRUE,  'T', "typedef",    "typedefs"},
    { TRUE,  'v', "variable",   "variable definitions"},
    { FALSE, 'x', "externvar",  "external variable declarations"}
};

static const keywordDesc KeywordTable [] = {
    /* 						    C++	           */
    /* 					     ANSI C  |  C# Java    */
    /* 					          |  |  |  |  Vera */
    /* keyword		keyword ID		  |  |  |  |  |    */
    { "__attribute__",	KEYWORD_ATTRIBUTE,	{ 1, 1, 1, 0, 0 } },
    { "abstract",	KEYWORD_ABSTRACT,	{ 0, 0, 1, 1, 0 } },
    { "bad_state",   	KEYWORD_BAD_STATE,   	{ 0, 0, 0, 0, 1 } },
    { "bad_trans",   	KEYWORD_BAD_TRANS,   	{ 0, 0, 0, 0, 1 } },
    { "bind",   	KEYWORD_BIND,   	{ 0, 0, 0, 0, 1 } },
    { "bind_var",   	KEYWORD_BIND_VAR,   	{ 0, 0, 0, 0, 1 } },
    { "bit",		KEYWORD_BIT,		{ 0, 0, 0, 0, 1 } },
    { "boolean",	KEYWORD_BOOLEAN,	{ 0, 0, 0, 1, 0 } },
    { "byte",		KEYWORD_BYTE,		{ 0, 0, 0, 1, 0 } },
    { "case",		KEYWORD_CASE,		{ 1, 1, 1, 1, 0 } },
    { "catch",		KEYWORD_CATCH,		{ 0, 1, 1, 0, 0 } },
    { "char",		KEYWORD_CHAR,		{ 1, 1, 1, 1, 0 } },
    { "class",		KEYWORD_CLASS,		{ 0, 1, 1, 1, 1 } },
    { "const",		KEYWORD_CONST,		{ 1, 1, 1, 1, 0 } },
    { "constraint",	KEYWORD_CONSTRAINT,	{ 0, 0, 0, 0, 1 } },
    { "coverage_block",	KEYWORD_COVERAGE_BLOCK,	{ 0, 0, 0, 0, 1 } },
    { "coverage_def",	KEYWORD_COVERAGE_DEF,	{ 0, 0, 0, 0, 1 } },
    { "do",		KEYWORD_DO,		{ 1, 1, 1, 1, 0 } },
    { "default",	KEYWORD_DEFAULT,	{ 1, 1, 1, 1, 0 } },
    { "delegate",	KEYWORD_DELEGATE,	{ 0, 0, 1, 0, 0 } },
    { "double",		KEYWORD_DOUBLE,		{ 1, 1, 1, 1, 0 } },
    { "else",		KEYWORD_ELSE,		{ 1, 1, 0, 1, 0 } },
    { "enum",		KEYWORD_ENUM,		{ 1, 1, 1, 0, 1 } },
    { "event",		KEYWORD_EVENT,		{ 0, 0, 1, 0, 1 } },
    { "explicit",	KEYWORD_EXPLICIT,	{ 0, 1, 1, 0, 0 } },
    { "extends",	KEYWORD_EXTENDS,	{ 0, 0, 0, 1, 1 } },
    { "extern",		KEYWORD_EXTERN,		{ 1, 1, 1, 0, 1 } },
    { "final",		KEYWORD_FINAL,		{ 0, 0, 0, 1, 0 } },
    { "float",		KEYWORD_FLOAT,		{ 1, 1, 1, 1, 0 } },
    { "for",		KEYWORD_FOR,		{ 1, 1, 1, 1, 0 } },
    { "friend",		KEYWORD_FRIEND,		{ 0, 1, 0, 0, 0 } },
    { "function",	KEYWORD_FUNCTION,	{ 0, 0, 0, 0, 1 } },
    { "goto",		KEYWORD_GOTO,		{ 1, 1, 1, 1, 0 } },
    { "if",		KEYWORD_IF,		{ 1, 1, 1, 1, 0 } },
    { "implements",	KEYWORD_IMPLEMENTS,	{ 0, 0, 0, 1, 0 } },
    { "import",		KEYWORD_IMPORT,		{ 0, 0, 0, 1, 0 } },
    { "inline",		KEYWORD_INLINE,		{ 0, 1, 0, 0, 0 } },
    { "inout",		KEYWORD_INOUT,		{ 0, 0, 0, 0, 1 } },
    { "input",		KEYWORD_INPUT,		{ 0, 0, 0, 0, 1 } },
    { "int",		KEYWORD_INT,		{ 1, 1, 1, 1, 0 } },
    { "integer",	KEYWORD_INTEGER,	{ 0, 0, 0, 0, 1 } },
    { "interface",	KEYWORD_INTERFACE,	{ 0, 0, 1, 1, 1 } },
    { "internal",	KEYWORD_INTERNAL,	{ 0, 0, 1, 0, 0 } },
    { "local",		KEYWORD_LOCAL,		{ 0, 0, 0, 0, 1 } },
    { "long",		KEYWORD_LONG,		{ 1, 1, 1, 1, 0 } },
    { "m_bad_state",	KEYWORD_M_BAD_STATE,	{ 0, 0, 0, 0, 1 } },
    { "m_bad_trans",	KEYWORD_M_BAD_TRANS,	{ 0, 0, 0, 0, 1 } },
    { "m_state",	KEYWORD_M_STATE,	{ 0, 0, 0, 0, 1 } },
    { "m_trans",	KEYWORD_M_TRANS,	{ 0, 0, 0, 0, 1 } },
    { "mutable",	KEYWORD_MUTABLE,	{ 0, 1, 0, 0, 0 } },
    { "namespace",	KEYWORD_NAMESPACE,	{ 0, 1, 1, 0, 0 } },
    { "native",		KEYWORD_NATIVE,		{ 0, 0, 0, 1, 0 } },
    { "new",		KEYWORD_NEW,		{ 0, 1, 1, 1, 0 } },
    { "newcov",		KEYWORD_NEWCOV,		{ 0, 0, 0, 0, 1 } },
    { "operator",	KEYWORD_OPERATOR,	{ 0, 1, 1, 0, 0 } },
    { "output",		KEYWORD_OUTPUT,		{ 0, 0, 0, 0, 1 } },
    { "overload",	KEYWORD_OVERLOAD,	{ 0, 1, 0, 0, 0 } },
    { "override",	KEYWORD_OVERRIDE,	{ 0, 0, 1, 0, 0 } },
    { "package",	KEYWORD_PACKAGE,	{ 0, 0, 0, 1, 0 } },
    { "packed",		KEYWORD_PACKED,		{ 0, 0, 0, 0, 1 } },
    { "port",		KEYWORD_PORT,		{ 0, 0, 0, 0, 1 } },
    { "private",	KEYWORD_PRIVATE,	{ 0, 1, 1, 1, 0 } },
    { "program",	KEYWORD_PROGRAM,	{ 0, 0, 0, 0, 1 } },
    { "protected",	KEYWORD_PROTECTED,	{ 0, 1, 1, 1, 1 } },
    { "public",		KEYWORD_PUBLIC,		{ 0, 1, 1, 1, 1 } },
    { "register",	KEYWORD_REGISTER,	{ 1, 1, 0, 0, 0 } },
    { "return",		KEYWORD_RETURN,		{ 1, 1, 1, 1, 0 } },
    { "shadow",		KEYWORD_SHADOW,		{ 0, 0, 0, 0, 1 } },
    { "short",		KEYWORD_SHORT,		{ 1, 1, 1, 1, 0 } },
    { "signed",		KEYWORD_SIGNED,		{ 1, 1, 0, 0, 0 } },
    { "state",		KEYWORD_STATE,		{ 0, 0, 0, 0, 1 } },
    { "static",		KEYWORD_STATIC,		{ 1, 1, 1, 1, 1 } },
    { "string",		KEYWORD_STRING,		{ 0, 0, 1, 0, 1 } },
    { "struct",		KEYWORD_STRUCT,		{ 1, 1, 1, 0, 0 } },
    { "switch",		KEYWORD_SWITCH,		{ 1, 1, 1, 1, 0 } },
    { "synchronized",	KEYWORD_SYNCHRONIZED,	{ 0, 0, 0, 1, 0 } },
    { "task",		KEYWORD_TASK,		{ 0, 0, 0, 0, 1 } },
    { "template",	KEYWORD_TEMPLATE,	{ 0, 1, 0, 0, 0 } },
    { "this",		KEYWORD_THIS,		{ 0, 1, 1, 1, 0 } },
    { "throw",		KEYWORD_THROW,		{ 0, 1, 1, 1, 0 } },
    { "throws",		KEYWORD_THROWS,		{ 0, 0, 0, 1, 0 } },
    { "trans",		KEYWORD_TRANS,		{ 0, 0, 0, 0, 1 } },
    { "transition",	KEYWORD_TRANSITION,	{ 0, 0, 0, 0, 1 } },
    { "transient",	KEYWORD_TRANSIENT,	{ 0, 0, 0, 1, 0 } },
    { "try",		KEYWORD_TRY,		{ 0, 1, 1, 0, 0 } },
    { "typedef",	KEYWORD_TYPEDEF,	{ 1, 1, 1, 0, 1 } },
    { "typename",	KEYWORD_TYPENAME,	{ 0, 1, 0, 0, 0 } },
    { "uint",		KEYWORD_UINT,		{ 0, 0, 1, 0, 0 } },
    { "ulong",		KEYWORD_ULONG,		{ 0, 0, 1, 0, 0 } },
    { "union",		KEYWORD_UNION,		{ 1, 1, 0, 0, 0 } },
    { "unsigned",	KEYWORD_UNSIGNED,	{ 1, 1, 1, 0, 0 } },
    { "ushort",		KEYWORD_USHORT,		{ 0, 0, 1, 0, 0 } },
    { "using",		KEYWORD_USING,		{ 0, 1, 1, 0, 0 } },
    { "virtual",	KEYWORD_VIRTUAL,	{ 0, 1, 1, 0, 1 } },
    { "void",		KEYWORD_VOID,		{ 1, 1, 1, 1, 1 } },
    { "volatile",	KEYWORD_VOLATILE,	{ 1, 1, 1, 1, 0 } },

⌨️ 快捷键说明

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