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

📄 tok_io.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    t->tokno = TOK_OTHER;
	    break;
	} else if (ISSPACE(c)) {
	    COLLECT(t->vstr, c, ISSPACE(c));
	    t->tokno = TOK_WSPACE;
	    break;
	} else if (ISALPHA(c)) {
	    COLLECT(t->vstr, c, ISALNUM(c));
	    t->tokno = TOK_WORD;
	    break;
	} else if (isdigit(c)) {
	    COLLECT(t->vstr, c, isdigit(c));
	    t->tokno = TOK_NUMBER;
	    break;
	} else if (c == '"' || c == '\'') {
	    t->tokno = read_quoted(t->vstr, c);	/* detect missing end quote */
	    break;
	} else if (ISDOT(c)) {
	    COLLECT(t->vstr, c, ISDOT(c));
	    t->tokno = TOK_OTHER;
	    break;
	} else if (c == '#' && last_tokno == '\n') {
	    do_control();
	    continue;
	} else {
	    t->vstr->str[0] = c;
	    if (c == '\n') {
		in_line++;
		if (nl_compensate > 0) {	/* compensation for bs-nl */
		    UNPUT('\n');
		    nl_compensate--;
		}
	    } else if (c == '/') {
		if ((INPUT(d)) == '*') {
		    t->vstr->str[1] = d;	/* comment */
		    read_comment(t->vstr);
		    t->tokno = TOK_WSPACE;
		    break;
		} else {
		    if (d != EOF)
			UNPUT(d);
		}
	    } else if (c == '\\') {
		t->vstr->str[1] = (INPUT(c) == EOF ? 0 : c);
		t->vstr->str[2] = 0;
		t->tokno = TOK_OTHER;
		break;
	    }
	    t->vstr->str[1] = 0;
	    t->tokno = c;
	    break;
	}
    }
    last_tokno = t->tokno;
    t->end_line = in_line;
    return (t);
}

/* read_quoted - read string or character literal, canonicalize escapes */

static int read_quoted(vs, ch)
register struct vstring *vs;
int     ch;
{
    register char *cp = vs->str;
    register int c;
    int     ret = TOK_OTHER;

    *cp++ = ch;

    /*
     * Clobber the token type in case of a premature newline or EOF. This
     * prevents us from attempting to concatenate string constants with
     * broken ones that have no closing quote.
     */

    while (INPUT(c) != EOF) {
	if (c == '\n') {			/* newline in string */
	    UNPUT(c);
	    break;
	}
	if (VS_ADDCH(vs, cp, c) == 0)		/* store character */
	    fatal("out of memory");
	if (c == ch) {				/* closing quote */
	    ret = c;
	    break;
	}
	if (c == '\\') {			/* parse escape sequence */
	    if ((INPUT(c)) == EOF) {		/* EOF, punt */
		break;
	    } else if (c == 'a') {		/* \a -> audible bell */
		if ((cp = vs_strcpy(vs, cp, BELL)) == 0)
		    fatal("out of memory");
	    } else if (c == 'x') {		/* \xhh -> \nnn */
		cp = read_hex(vs, cp);
	    } else if (ISOCTAL(c) && ch != '\'') {
		cp = read_octal(vs, cp, c);	/* canonicalize \octal */
	    } else {
		if (VS_ADDCH(vs, cp, c) == 0)	/* \other: leave alone */
		    fatal("out of memory");
	    }
	}
    }
    *cp = 0;
    return (ret);
}

/* read_comment - stuff a whole comment into one huge token */

static void read_comment(vs)
register struct vstring *vs;
{
    register char *cp = vs->str + 2;	/* skip slash star */
    register int c;
    register int d;

    while (INPUT(c) != EOF) {
	if (VS_ADDCH(vs, cp, c) == 0)
	    fatal("out of memory");
	if (c == '*') {
	    if ((INPUT(d)) == '/') {
		if (VS_ADDCH(vs, cp, d) == 0)
		    fatal("out of memory");
		break;
	    } else {
		if (d != EOF)
		    UNPUT(d);
	    }
	} else if (c == '\n') {
	    in_line++;
	} else if (c == '\\') {
	    if ((INPUT(d)) != EOF && VS_ADDCH(vs, cp, d) == 0)
		fatal("out of memory");
	}
    }
    *cp = 0;
}

/* read_hex - rewrite hex escape to three-digit octal escape */

static char *read_hex(vs, cp)
struct vstring *vs;
register char *cp;
{
    register int c;
    register int i;
    char    buf[BUFSIZ];
    int     len;
    unsigned val;

    /*
     * Eat up all subsequent hex digits. Complain later when there are too
     * many.
     */

    for (i = 0; i < sizeof(buf) && (INPUT(c) != EOF) && ISHEX(c); i++)
	buf[i] = c;
    buf[i] = 0;

    if (i < sizeof(buf) && c)
	UNPUT(c);

    /*
     * Convert hex form to three-digit octal form. The three-digit form is
     * used so that strings can be concatenated without problems. Complain
     * about malformed input; truncate the result to at most three octal
     * digits.
     */

    if (i == 0) {
	error("\\x escape sequence without hexadecimal digits");
	if (VS_ADDCH(vs, cp, 'x') == 0)
	    fatal("out of memory");
    } else {
	(void) sscanf(buf, "%x", &val);
	sprintf(buf, "%03o", val);
	if ((len = strlen(buf)) > 3)
	    error("\\x escape sequence yields non-character value");
	if ((cp = vs_strcpy(vs, cp, buf + len - 3)) == 0)
	    fatal("out of memory");
    }
    return (cp);
}

/* read_octal - convert octal escape to three-digit format */

static char obuf[] = "00123";

static char *read_octal(vs, cp, c)
register struct vstring *vs;
register char *cp;
register int c;
{
    register int i;

#define	buf_input (obuf + 2)

    /* Eat up at most three octal digits. */

    buf_input[0] = c;
    for (i = 1; i < 3 && (INPUT(c) != EOF) && ISOCTAL(c); i++)
	buf_input[i] = c;
    buf_input[i] = 0;

    if (i < 3 && c)
	UNPUT(c);

    /*
     * Leave three-digit octal escapes alone. Convert one-digit and two-digit
     * octal escapes to three-digit form by prefixing them with a suitable
     * number of '0' characters. This is done so that strings can be
     * concatenated without problems.
     */

    if ((cp = vs_strcpy(vs, cp, buf_input + i - 3)) == 0)
	fatal("out of memory");
    return (cp);
}

/* put_nl - emit newline and adjust output line count */

void    put_nl()
{
    put_ch('\n');
    out_line++;
}

/* fix_line_control - to adjust path and/or line count info in output */

static void fix_line_control(path, line)
register char *path;
register int line;
{

    /*
     * This function is called sporadically, so it should not be a problem
     * that we repeat some of the tests that preceded this function call.
     * 
     * Emit a newline if we are not at the start of a line.
     * 
     * If we switch files, or if we jump backwards, emit line control. If we
     * jump forward, emit the proper number of newlines to compensate.
     */

    if (last_ch != '\n')			/* terminate open line */
	put_nl();
    if (path != out_path || line < out_line) {	/* file switch or back jump */
	printf("# %d %s\n", out_line = line, out_path = path);
	last_ch = '\n';
    } else {					/* forward jump */
	while (line > out_line)
	    put_nl();
    }
}

/* tok_show_ch - output single-character token (not newline) */

void    tok_show_ch(t)
register struct token *t;
{
    CHECK_LINE_CONTROL(t->path, t->line);

    put_ch(t->tokno);				/* show token contents */
}

/* tok_show - output (possibly composite) token */

void    tok_show(t)
register struct token *t;
{
    register struct token *p;

    if (t->tokno == TOK_LIST) {
	register struct token *s;

	/*
	 * This branch is completely in terms of tok_xxx() primitives, so
	 * there is no need to check the line control information.
	 */

	for (s = t->head; s; s = s->next) {
	    tok_show_ch(s);			/* '(' or ',' or ')' */
	    for (p = s->head; p; p = p->next)
		tok_show(p);			/* show list element */
	}
    } else {
	register char *cp = t->vstr->str;

	/*
	 * Measurements show that it pays off to give special treatment to
	 * single-character tokens. Note that both types of token may cause a
	 * change of output line number.
	 */

	CHECK_LINE_CONTROL(t->path, t->line);
	if (cp[1] == 0) {
	    put_ch(*cp);			/* single-character token */
	} else {
	    put_str(cp);			/* multi_character token */
	}
	out_line = t->end_line;			/* may span multiple lines */
	for (p = t->head; p; p = p->next)
	    tok_show(p);			/* trailing blanks */
    }
}

⌨️ 快捷键说明

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