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

📄 c.c

📁 Exuberant Ctags is a multilanguage reimplementation of the much-underused ctags(1) program and is i
💻 C
📖 第 1 页 / 共 5 页
字号:
/**   $Id: c.c,v 1.34 2006/05/30 04:37:11 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)       ((c) != EOF && (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_DELETE, 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;/* Number used to uniquely identify anonymous structs and unions. */static int AnonymousID = 0;/* 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 } },	{ "delete",         KEYWORD_DELETE,         { 0, 1, 0, 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 } },	{ "wchar_t",        KEYWORD_WCHAR_T,        { 1, 1, 1, 0, 0 } },	{ "while",          KEYWORD_WHILE,          { 1, 1, 1, 1, 0 } }};

⌨️ 快捷键说明

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