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

📄 get.c

📁 ultraEdit的Ctag标签工具的实现源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	readIdentifier (c, Cpp.directive.name);
	if (stringMatch (vStringValue (Cpp.directive.name), "weak"))
	{
	    /* generate macro tag for weak name */
	    do
	    {
		c = fileGetc ();
	    } while (c == SPACE);
	    if (isident1 (c))
	    {
		readIdentifier (c, Cpp.directive.name);
		makeDefineTag (vStringValue (Cpp.directive.name));
	    }
	}
    }
    Cpp.directive.state = DRCTV_NONE;
}

static boolean directiveIf (const int c)
{
    DebugStatement ( const boolean ignore0 = isIgnore (); )
    const boolean ignore = pushConditional ((boolean) (c != '0'));

    Cpp.directive.state = DRCTV_NONE;
    DebugStatement ( debugCppNest (TRUE, Cpp.directive.nestLevel);
		    if (ignore != ignore0) debugCppIgnore (ignore); )

    return ignore;
}

static boolean directiveHash (const int c)
{
    boolean ignore = FALSE;
    char directive [MaxDirectiveName];
    DebugStatement ( const boolean ignore0 = isIgnore (); )

    readDirective (c, directive, MaxDirectiveName);
    if (stringMatch (directive, "define"))
	Cpp.directive.state = DRCTV_DEFINE;
    else if (stringMatch (directive, "undef"))
	Cpp.directive.state = DRCTV_UNDEF;
    else if (strncmp (directive, "if", (size_t) 2) == 0)
	Cpp.directive.state = DRCTV_IF;
    else if (stringMatch (directive, "elif")  ||
	    stringMatch (directive, "else"))
    {
	ignore = setIgnore (isIgnoreBranch ());
	if (! ignore  &&  stringMatch (directive, "else"))
	    chooseBranch ();
	Cpp.directive.state = DRCTV_NONE;
	DebugStatement ( if (ignore != ignore0) debugCppIgnore (ignore); )
    }
    else if (stringMatch (directive, "endif"))
    {
	DebugStatement ( debugCppNest (FALSE, Cpp.directive.nestLevel); )
	ignore = popConditional ();
	Cpp.directive.state = DRCTV_NONE;
	DebugStatement ( if (ignore != ignore0) debugCppIgnore (ignore); )
    }
    else if (stringMatch (directive, "pragma"))
	Cpp.directive.state = DRCTV_PRAGMA;
    else
	Cpp.directive.state = DRCTV_NONE;

    return ignore;
}

/*  Handles a pre-processor directive whose first character is given by "c".
 */
static boolean handleDirective (const int c)
{
    boolean ignore = FALSE;

    switch (Cpp.directive.state)
    {
	case DRCTV_NONE:	ignore = isIgnore ();		break;
	case DRCTV_DEFINE:	directiveDefine (c);		break;
	case DRCTV_HASH:	ignore = directiveHash (c);	break;
	case DRCTV_IF:		ignore = directiveIf (c);	break;
	case DRCTV_PRAGMA:	directivePragma (c);		break;
	case DRCTV_UNDEF:	directiveDefine (c);		break;
    }
    return ignore;
}

/*  Called upon reading of a slash ('/') characters, determines whether a
 *  comment is encountered, and its type.
 */
static Comment isComment (void)
{
    Comment comment;
    const int next = fileGetc ();

    if (next == '*')
	comment = COMMENT_C;
    else if (next == '/')
	comment = COMMENT_CPLUS;
    else
    {
	fileUngetc (next);
	comment = COMMENT_NONE;
    }
    return comment;
}

/*  Skips over a C style comment. According to ANSI specification a comment
 *  is treated as white space, so we perform this subsitution.
 */
static int skipOverCComment (void)
{
    int c = fileGetc ();

    while (c != EOF)
    {
	if (c != '*')
	    c = fileGetc ();
	else
	{
	    const int next = fileGetc ();

	    if (next != '/')
		c = next;
	    else
	    {
		c = SPACE;		/* replace comment with space */
		break;
	    }
	}
    }
    return c;
}

/*  Skips over a C++ style comment.
 */
static int skipOverCplusComment (void)
{
    int c;

    while ((c = fileGetc ()) != EOF)
    {
	if (c == BACKSLASH)
	    fileGetc ();		/* throw away next character, too */
	else if (c == NEWLINE)
	    break;
    }
    return c;
}

/*  Skips to the end of a string, returning a special character to
 *  symbolically represent a generic string.
 */
static int skipToEndOfString (void)
{
    int c;

    while ((c = fileGetc ()) != EOF)
    {
	if (c == BACKSLASH)
	    fileGetc ();		/* throw away next character, too */
	else if (c == DOUBLE_QUOTE)
	    break;
    }
    return STRING_SYMBOL;		/* symbolic representation of string */
}

/*  Skips to the end of the three (possibly four) 'c' sequence, returning a
 *  special character to symbolically represent a generic character.
 *  Also detects Vera numbers that include a base specifier (ie. 'b1010).
 */
static int skipToEndOfChar (void)
{
    int c;
    int count = 0, veraBase = '\0';

    while ((c = fileGetc ()) != EOF)
    {
        ++count;
	if (c == BACKSLASH)
	    fileGetc ();		/* throw away next character, too */
	else if (c == SINGLE_QUOTE)
	    break;
	else if (c == NEWLINE)
	{
	    fileUngetc (c);
	    break;
	}
	else if (count == 1  &&  strchr ("DHOB", toupper (c)) != NULL)
	    veraBase = c;
	else if (veraBase != '\0'  &&  ! isalnum (c))
	{
	    fileUngetc (c);
	    break;
	}
    }
    return CHAR_SYMBOL;		    /* symbolic representation of character */
}

/*  This function returns the next character, stripping out comments,
 *  C pre-processor directives, and the contents of single and double
 *  quoted strings. In short, strip anything which places a burden upon
 *  the tokenizer.
 */
extern int cppGetc (void)
{
    boolean directive = FALSE;
    boolean ignore = FALSE;
    int c;

    if (Cpp.ungetch != '\0')
    {
	c = Cpp.ungetch;
	Cpp.ungetch = Cpp.ungetch2;
	Cpp.ungetch2 = '\0';
	return c;	    /* return here to avoid re-calling debugPutc () */
    }
    else do
    {
	c = fileGetc ();
process:
	switch (c)
	{
	    case EOF:
		ignore    = FALSE;
		directive = FALSE;
		break;

	    case TAB:
	    case SPACE:
		break;				/* ignore most white space */

	    case NEWLINE:
		if (directive  &&  ! ignore)
		    directive = FALSE;
		Cpp.directive.accept = TRUE;
		break;

	    case DOUBLE_QUOTE:
		Cpp.directive.accept = FALSE;
		c = skipToEndOfString ();
		break;

	    case '#':
		if (Cpp.directive.accept)
		{
		    directive = TRUE;
		    Cpp.directive.state  = DRCTV_HASH;
		    Cpp.directive.accept = FALSE;
		}
		break;

	    case SINGLE_QUOTE:
		Cpp.directive.accept = FALSE;
		c = skipToEndOfChar ();
		break;

	    case '/':
	    {
		const Comment comment = isComment ();

		if (comment == COMMENT_C)
		    c = skipOverCComment ();
		else if (comment == COMMENT_CPLUS)
		{
		    c = skipOverCplusComment ();
		    if (c == NEWLINE)
			fileUngetc (c);
		}
		else
		    Cpp.directive.accept = FALSE;
		break;
	    }

	    case BACKSLASH:
	    {
		int next = fileGetc ();

		if (next == NEWLINE)
		    continue;
		else if (next == '?')
		    cppUngetc (next);
		else
		    fileUngetc (next);
		break;
	    }

	    case '?':
	    {
		int next = fileGetc ();
		if (next != '?')
		    fileUngetc (next);
		else
		{
		    next = fileGetc ();
		    switch (next)
		    {
			case '(':          c = '[';       break;
			case ')':          c = ']';       break;
			case '<':          c = '{';       break;
			case '>':          c = '}';       break;
			case '/':          c = BACKSLASH; goto process;
			case '!':          c = '|';       break;
			case SINGLE_QUOTE: c = '^';       break;
			case '-':          c = '~';       break;
			case '=':          c = '#';       goto process;
			default:
			    fileUngetc (next);
			    cppUngetc ('?');
			    break;
		    }
		}
	    } break;

	    default:
		Cpp.directive.accept = FALSE;
		if (directive)
		    ignore = handleDirective (c);
		break;
	}
    } while (directive || ignore);

    DebugStatement ( debugPutc (DEBUG_CPP, c); )
    DebugStatement ( if (c == NEWLINE)
		debugPrintf (DEBUG_CPP, "%6ld: ", getInputLineNumber () + 1); )

    return c;
}

/* vi:set tabstop=8 shiftwidth=4: */

⌨️ 快捷键说明

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