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

📄 tcc.c

📁 Tiny C&C++,看看吧,也许用的着
💻 C
📖 第 1 页 / 共 5 页
字号:
            file->buf_ptr = p;            c = handle_eob();            p = file->buf_ptr;            if (c == '\\') {                PEEKC_EOB(c, p);                if (c == '\n') {                    file->line_num++;                    PEEKC_EOB(c, p);                } else if (c == '\r') {                    PEEKC_EOB(c, p);                    if (c == '\n') {                        file->line_num++;                        PEEKC_EOB(c, p);                    }                }            } else {                goto redo;            }        } else {            p++;        }    }    return p;}/* C comments */static uint8_t *parse_comment(uint8_t *p){    int c;        p++;    for(;;) {        /* fast skip loop */        for(;;) {            c = *p;            if (c == '\n' || c == '*' || c == '\\')                break;            p++;            c = *p;            if (c == '\n' || c == '*' || c == '\\')                break;            p++;        }        /* now we can handle all the cases */        if (c == '\n') {            file->line_num++;            p++;        } else if (c == '*') {            p++;            for(;;) {                c = *p;                if (c == '*') {                    p++;                } else if (c == '/') {                    goto end_of_comment;                } else if (c == '\\') {                    file->buf_ptr = p;                    c = handle_eob();                    p = file->buf_ptr;                    if (c == '\\') {                        /* skip '\[\r]\n', otherwise just skip the stray */                        while (c == '\\') {                            PEEKC_EOB(c, p);                            if (c == '\n') {                                file->line_num++;                                PEEKC_EOB(c, p);                            } else if (c == '\r') {                                PEEKC_EOB(c, p);                                if (c == '\n') {                                    file->line_num++;                                    PEEKC_EOB(c, p);                                }                            } else {                                goto after_star;                            }                        }                    }                } else {                    break;                }            }        after_star: ;        } else {            /* stray, eob or eof */            file->buf_ptr = p;            c = handle_eob();            p = file->buf_ptr;            if (c == CH_EOF) {                error("unexpected end of file in comment");            } else if (c == '\\') {                p++;            }        }    } end_of_comment:    p++;    return p;}#define cinp minp/* space exlcuding newline */static inline int is_space(int ch){    return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';}static inline void skip_spaces(void){    while (is_space(ch))        cinp();}/* parse a string without interpreting escapes */static uint8_t *parse_pp_string(uint8_t *p,                                int sep, CString *str){    int c;    p++;    for(;;) {        c = *p;        if (c == sep) {            break;        } else if (c == '\\') {            file->buf_ptr = p;            c = handle_eob();            p = file->buf_ptr;            if (c == CH_EOF) {            unterminated_string:                /* XXX: indicate line number of start of string */                error("missing terminating %c character", sep);            } else if (c == '\\') {                /* escape : just skip \[\r]\n */                PEEKC_EOB(c, p);                if (c == '\n') {                    file->line_num++;                    p++;                } else if (c == '\r') {                    PEEKC_EOB(c, p);                    if (c != '\n')                        expect("'\n' after '\r'");                    file->line_num++;                    p++;                } else if (c == CH_EOF) {                    goto unterminated_string;                } else {                    if (str) {                        cstr_ccat(str, '\\');                        cstr_ccat(str, c);                    }                    p++;                }            }        } else if (c == '\n') {            file->line_num++;            goto add_char;        } else if (c == '\r') {            PEEKC_EOB(c, p);            if (c != '\n') {                if (str)                    cstr_ccat(str, '\r');            } else {                file->line_num++;                goto add_char;            }        } else {        add_char:            if (str)                cstr_ccat(str, c);            p++;        }    }    p++;    return p;}/* skip block of text until #else, #elif or #endif. skip also pairs of   #if/#endif */void preprocess_skip(void){    int a, start_of_line, c;    uint8_t *p;    p = file->buf_ptr;    start_of_line = 1;    a = 0;    for(;;) {    redo_no_start:        c = *p;        switch(c) {        case ' ':        case '\t':        case '\f':        case '\v':        case '\r':            p++;            goto redo_no_start;        case '\n':            start_of_line = 1;            file->line_num++;            p++;            goto redo_no_start;        case '\\':            file->buf_ptr = p;            c = handle_eob();            if (c == CH_EOF) {                expect("#endif");            } else if (c == '\\') {                /* XXX: incorrect: should not give an error */                ch = file->buf_ptr[0];                handle_stray();            }            p = file->buf_ptr;            goto redo_no_start;            /* skip strings */        case '\"':        case '\'':            p = parse_pp_string(p, c, NULL);            break;            /* skip comments */        case '/':            file->buf_ptr = p;            ch = *p;            minp();            p = file->buf_ptr;            if (ch == '*') {                p = parse_comment(p);            } else if (ch == '/') {                p = parse_line_comment(p);            }            break;        case '#':            p++;            if (start_of_line) {                file->buf_ptr = p;                next_nomacro();                p = file->buf_ptr;                if (a == 0 &&                     (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))                    goto the_end;                if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)                    a++;                else if (tok == TOK_ENDIF)                    a--;            }            break;        default:            p++;            break;        }        start_of_line = 0;    } the_end: ;    file->buf_ptr = p;}/* ParseState handling *//* XXX: currently, no include file info is stored. Thus, we cannot display   accurate messages if the function or data definition spans multiple   files *//* save current parse state in 's' */void save_parse_state(ParseState *s){    s->line_num = file->line_num;    s->macro_ptr = macro_ptr;    s->tok = tok;    s->tokc = tokc;}/* restore parse state from 's' */void restore_parse_state(ParseState *s){    file->line_num = s->line_num;    macro_ptr = s->macro_ptr;    tok = s->tok;    tokc = s->tokc;}/* return the number of additional 'ints' necessary to store the   token */static inline int tok_ext_size(int t){    switch(t) {        /* 4 bytes */    case TOK_CINT:    case TOK_CUINT:    case TOK_CCHAR:    case TOK_LCHAR:    case TOK_CFLOAT:    case TOK_LINENUM:        return 1;    case TOK_STR:    case TOK_LSTR:    case TOK_PPNUM:        error("unsupported token");        return 1;    case TOK_CDOUBLE:    case TOK_CLLONG:    case TOK_CULLONG:        return 2;    case TOK_CLDOUBLE:        return LDOUBLE_SIZE / 4;    default:        return 0;    }}/* token string handling */static inline void tok_str_new(TokenString *s){    s->str = NULL;    s->len = 0;    s->allocated_len = 0;    s->last_line_num = -1;}static void tok_str_free(int *str){    tcc_free(str);}static int *tok_str_realloc(TokenString *s){    int *str, len;    if (s->allocated_len == 0) {        len = 8;    } else {        len = s->allocated_len * 2;    }    str = tcc_realloc(s->str, len * sizeof(int));    if (!str)        error("memory full");    s->allocated_len = len;    s->str = str;    return str;}static void tok_str_add(TokenString *s, int t){    int len, *str;    len = s->len;    str = s->str;    if (len >= s->allocated_len)        str = tok_str_realloc(s);    str[len++] = t;    s->len = len;}static void tok_str_add2(TokenString *s, int t, CValue *cv){    int len, *str;    len = s->len;    str = s->str;    /* allocate space for worst case */    if (len + TOK_MAX_SIZE > s->allocated_len)        str = tok_str_realloc(s);    str[len++] = t;    switch(t) {    case TOK_CINT:    case TOK_CUINT:    case TOK_CCHAR:    case TOK_LCHAR:    case TOK_CFLOAT:    case TOK_LINENUM:        str[len++] = cv->tab[0];        break;    case TOK_PPNUM:    case TOK_STR:    case TOK_LSTR:        {            int nb_words;            CString *cstr;            nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2;            while ((len + nb_words) > s->allocated_len)                str = tok_str_realloc(s);            cstr = (CString *)(str + len);            cstr->data = NULL;            cstr->size = cv->cstr->size;            cstr->data_allocated = NULL;            cstr->size_allocated = cstr->size;            memcpy((char *)cstr + sizeof(CString),                    cv->cstr->data, cstr->size);            len += nb_words;        }        break;    case TOK_CDOUBLE:    case TOK_CLLONG:    case TOK_CULLONG:#if LDOUBLE_SIZE == 8    case TOK_CLDOUBLE:#endif        str[len++] = cv->tab[0];        str[len++] = cv->tab[1];        break;#if LDOUBLE_SIZE == 12    case TOK_CLDOUBLE:        str[len++] = cv->tab[0];        str[len++] = cv->tab[1];        str[len++] = cv->tab[2];#elif LDOUBLE_SIZE != 8#error add long double size support#endif        break;    default:        break;    }    s->len = len;}/* add the current parse token in token string 's' */static void tok_str_add_tok(TokenString *s){    CValue cval;    /* save line number info */    if (file->line_num != s->last_line_num) {        s->last_line_num = file->line_num;        cval.i = s->last_line_num;        tok_str_add2(s, TOK_LINENUM, &cval);    }    tok_str_add2(s, tok, &tokc);}#if LDOUBLE_SIZE == 12#define LDOUBLE_GET(p, cv)                      \        cv.tab[0] = p[0];                       \        cv.tab[1] = p[1];                       \        cv.tab[2] = p[2];#elif LDOUBLE_SIZE == 8#define LDOUBLE_GET(p, cv)                      \        cv.tab[0] = p[0];                       \        cv.tab[1] = p[1];#else#error add long double size support#endif/* get a token from an integer array and increment pointer   accordingly. we code it as a macro to avoid pointer aliasing. */#define TOK_GET(t, p, cv)                       \{                                               \    t = *p++;                                   \    switch(t) {                                 \    case TOK_CINT:                              \    case TOK_CUINT:                             \    case TOK_CCHAR:                             \    case TOK_LCHAR:                             \    case TOK_CFLOAT:                            \    case TOK_LINENUM:                           \        cv.tab[0] = *p++;                       \        break;                                  \    case TOK_STR:                               \    case TOK_LSTR:                              \    case TOK_PPNUM:                             \        cv.cstr = (CString *)p;                 \        cv.cstr->data = (char *)p + sizeof(CString);\        p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\        break;                                  \    case TOK_CDOUBLE:                           \    case TOK_CLLONG:                            \    case TOK_CULLONG:                           \        cv.tab[0] = p[0];                       \        cv.tab[1] = p[1];                       \        p += 2;                                 \        break;                                  \    case TOK_CLDOUBLE:                          \        LDOUBLE_GET(p, cv);                     \        p += LDOUBLE_SIZE / 4;                  \        break;                                  \    default:                                    \        break;                                  \    }                                           \

⌨️ 快捷键说明

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