Alien-TinyCCx

 view release on metacpan or  search on metacpan

src/tccexsymtab.c  view on Meta::CPAN

enum {
    TS_TEST_GET_TOK,
    TS_TEST_HAS_DEFINE,
    TS_TEST_HAS_STRUCT,
    TS_TEST_HAS_IDENTIFIER
};

LIBTCCAPI int tcc_extended_symtab_test(extended_symtab_p symtab, int to_test, const char * name)
{
    TokenSym * ts;

    /* Get the tokenSym by the given name */
    ts = *token_string_hash_get_ref(symtab->tsh, name);
    if (ts == NULL) return 0;

    /* Perform the requested test */
    switch(to_test) {
        case TS_TEST_GET_TOK:
            return ts->tok;
        case TS_TEST_HAS_DEFINE:
            return ts->sym_define != NULL;
        case TS_TEST_HAS_IDENTIFIER:
            return ts->sym_identifier != NULL;
        case TS_TEST_HAS_STRUCT:
            return ts->sym_struct != NULL;
    }
    return 0;
}

/*****************************************************************************/
/*                      Pre-compilation TokenSym Prep                        */
/*****************************************************************************/

LIBTCCAPI void tcc_prep_tokensym_list(extended_symtab * symtab)
{
    int i;
    for (i = 0; i < symtab->tok_start_offset; i++)
    {
        TokenSym * ext_ts = symtab->tokenSym_list[i];
        int flagless_tok = ext_ts->tok & ~(SYM_STRUCT | SYM_FIELD | SYM_EXTENDED | SYM_FIRST_ANOM);
        TokenSym * local_ts = table_ident[flagless_tok - TOK_IDENT];

        /* Skip if we've already copied something for this TokenSym from another
         * extended symbol table, since it'll never get looked up in this
         * extended symbol table. */

        if (local_ts->sym_struct || local_ts->sym_identifier || local_ts->sym_define) continue;

        /* Copy */
        copy_extended_tokensym(symtab, ext_ts, local_ts);
    }
}

/*****************************************************************************/
/*                      copy extended symbol into local                      */
/*****************************************************************************/

/* Provide a mechanism for turning the local_stack off and back on outside of
 * the current static file scope. */

ST_DATA Sym * local_stack_backup;
void local_stack_off() {
    local_stack_backup = local_stack;
    local_stack = NULL;
}
void local_stack_on() {
    local_stack = local_stack_backup;
}

/* The define token stream is a series of bytes. They are collections of
 * integer => data pairs, where the integer indicates the type (and thus size)
 * of the data that follows. For example, if we encounter types TOK_PPNUM,
 * TOK_STR, or TOK_LSTR, then the next few bytes are a CString struct (mostly
 * filled with NULLs) followed by the associated character string. It gets
 * complicated, but has only a handful of special cases to handle. The formats
 * of the stream are codified in tok_str_add2, which is defined in tccpp.c.
 * 
 * This function returns the length of a tokenstream, including the final
 * null. If it is given a target tokenstream, it assumes that the
 * contents of the original have already been copied to the target
 * using memcpy, in which case it updates the token ids for arbitrary
 * tokens (function names, variable names, etc). Using the macro for
 * tokenstream_len defined in tccexsymtab.h, proper usage is:
 * 
 *   int len = tokenstream_len (stream_to_copy); // implicitly calls tokenstream_copy
 *   int * new = malloc(len * sizeof(int));
 *   memcpy(new, stream_to_copy, len * sizeof(int));
 *   tokenstream_copy(stream_to_copy, new, symtab);
 * 
 * Note that the final symtab pointer is the symtab associated with the
 * input stream, not the output stream.
 */

int tokenstream_copy (int * stream, int * to_stream, extended_symtab * symtab)
{
    int len;

    /* handle dumb user edge cases: either both to_stream and symtab
     * are null, or they are both specified. */

    if (to_stream == 0) symtab = 0;
    if (symtab == 0) to_stream = 0;

    len = 0;
    while(stream[len] != 0)
    {
        /* One for the type */
        len++;
        switch(stream[len-1])
        {
            case TOK_CINT: case TOK_CUINT: case TOK_CCHAR:
            case TOK_LCHAR: case TOK_CFLOAT: case TOK_LINENUM:
                len++;
                break;
            case TOK_PPNUM: case TOK_PPSTR: case TOK_STR: case TOK_LSTR:
                {
                    CString *cstr = (CString *)(stream + len);
                    len += 1 + (cstr->size + sizeof(int) - 1) / sizeof(int);

                    /* If copying, then one might naively expect that I
                     * should set up cstr to be usable for later
                     * preprocessor expansions. See tok_str_add2 in
                     * tccpp.c for details. However, the memcpy that was
                     * presumably performed prior to calling this
                     * function already did that! So I'm done. */
                }
                break;



( run in 3.126 seconds using v1.01-cache-2.11-cpan-dd78ea5b424 )