Esempio n. 1
0
char* find_define(define *d, char* m) {
	define *curr = d;
	while (curr != NULL) {
		if (strcmp(curr->macro, m) == 0) {
			/* we have to recursively check for nested defines */
			if (find_define(d, curr->expansion) != NULL)
				return find_define(d, curr->expansion);
			return curr->expansion;
		}
		curr = curr->next;
	}
	return NULL;
}
Esempio n. 2
0
void add_simple_define( char * macro, char *text )
{
    int code = identifier_search_or_add( macro );

    if ( find_define( code ) != -1 ) compile_error( MSG_MACRO_ERROR, identifier_name( code ) );

    /* Allocate the macro */

    if ( defines_allocated == defines_count )
    {
        defines_allocated += 8;
        defines = ( DEFINE * ) realloc( defines, sizeof( DEFINE ) * defines_allocated );
    }

    defines[defines_count].param_count = -1;
    defines[defines_count].code = code;
    defines[defines_count].text = strdup( text );
    defines_count++;
}
Esempio n. 3
0
void preprocessor()
{
    int i, ifdef;
    char * ptr;
    int actual_line_count;

    static int initialized = 0;

    if ( !initialized )
    {
        id_define  = identifier_search_or_add( "DEFINE" );
        id_undef   = identifier_search_or_add( "UNDEF" );
        id_ifdef   = identifier_search_or_add( "IFDEF" );
        id_ifndef  = identifier_search_or_add( "IFNDEF" );
        id_else    = identifier_search_or_add( "ELSE" );
        id_endif   = identifier_search_or_add( "ENDIF" );
        id_if      = identifier_search_or_add( "IF" );
        initialized = 1;
    }

    token_next();

    if ( token.type != IDENTIFIER ) compile_error( MSG_UNKNOWN_PREP );

    /* #define TEXT value */

    if ( token.code == id_define )
    {
        disable_expand_defines++;

        token_next();
        if ( token.type != IDENTIFIER ) compile_error( MSG_INVALID_IDENTIFIER );

        if ( find_define( token.code ) != -1 ) compile_error( MSG_MACRO_ERROR, identifier_name( token.code ) );

        /* Allocate the macro */

        if ( defines_allocated == defines_count )
        {
            defines_allocated += 8;
            defines = ( DEFINE * ) realloc( defines, sizeof( DEFINE ) * defines_allocated );
        }

        defines[defines_count].code = token.code;

        /* Check for parameters: no space allowed between name and ( */

        if ( *source_ptr == '(' )
        {
            source_ptr++;
            for ( defines[defines_count].param_count = i = 0; *source_ptr != ')'; )
            {
                if ( !*source_ptr ) compile_error( MSG_EXPECTED, ")" );
                if ( i == MAX_MACRO_PARAMS ) compile_error( MSG_TOO_MANY_PARAMS );
                token_next();

                if ( token.type != IDENTIFIER || token.code < reserved_words ) compile_error( MSG_INVALID_IDENTIFIER );

                defines[defines_count].param_id[i++] = token.code;
                defines[defines_count].param_count++;

                SKIP_SPACES;
                if ( *source_ptr == ',' ) source_ptr++;
            }
            source_ptr++;
        }
        else
        {
            /* No parameters and no parenthesis */
            defines[defines_count].param_count = -1;
        }

        SKIP_SPACES_UNTIL_LF_AND_COUNT_LINES;

        ptr = ( char * ) source_ptr;

        while ( *ptr && *ptr != '\n' )
            if ( *ptr == '\\' && *( ptr + 1 ) == '\n' )
            {
                *ptr = ' ';
                ptr++;
                *ptr = ' ';
                ptr++;
                line_count++;
            }
            else
                ptr++;

        while ( ptr > source_ptr && ( !*ptr || ISSPACE( *ptr ) ) ) ptr--;

        defines[defines_count].text = ( char * )calloc( ptr - source_ptr + 2, sizeof( char ) );
        strncpy( defines[defines_count].text, source_ptr, ptr - source_ptr + 1 );
        defines[defines_count].text[ptr - source_ptr + 1] = 0;

        defines_count++;

        source_ptr = ptr + 1;

        disable_expand_defines--;

        return;
    }

    /* #undef TEXT */

    if ( token.code == id_undef )
    {
        disable_expand_defines++;

        token_next();
        if ( token.type != IDENTIFIER ) compile_error( MSG_INVALID_IDENTIFIER );

        if (( i = find_define( token.code ) ) != -1 )
        {
            defines_count--;
            if ( defines[i].text ) free( defines[i].text );
            memmove( &defines[i], &defines[i+1], ( defines_count - i ) * sizeof( DEFINE ) );
        }

        disable_expand_defines--;

        return;
    }

    /* #ifdef CONST / #ifndef CONST*/

    if ( token.code == id_ifdef || token.code == id_ifndef )
    {
        ifdef = token.code == id_ifdef;

        prepro_stack[prepro_sp++] = token.code;

        disable_expand_defines++;
        token_next();
        disable_expand_defines--;

        if ( token.type != IDENTIFIER ) compile_error( MSG_INVALID_IDENTIFIER );

        SKIP_SPACES_UNTIL_LF_AND_COUNT_LINES;
        if ( *source_ptr && *source_ptr != '\n' )
        {
            if ( ifdef ) compile_warning( "extra tokens at end of #ifdef directive" );
            else compile_warning( "extra tokens at end of #ifndef directive" );
            SKIP_ALL_UNTIL_LF_AND_COUNT_LINES;
        }

        if ( *source_ptr == '\n' ) line_count--;

        for ( i = 0; i < defines_count; i++ )
        {
            if ( defines[i].code == token.code )
            {
                if ( ifdef ) return;
                break;
            }
        }
        if ( !ifdef && i == defines_count ) return;


        preprocessor_jumpto( id_else, id_endif );

        SKIP_SPACES_UNTIL_LF_AND_COUNT_LINES;
        if ( *source_ptr && *source_ptr != '\n' )
        {
            if ( token.code == id_else ) compile_warning( "extra tokens at end of #else directive" );
            else if ( token.code == id_endif ) compile_warning( "extra tokens at end of #endif directive" );
            SKIP_ALL_UNTIL_LF_AND_COUNT_LINES;
        }
        if ( *source_ptr == '\n' ) line_count--;
        return;
    }

    /* #if */

    if ( token.code == id_if )
    {
        int actual_sources;
        expresion_result res;
        char c;

        prepro_stack[prepro_sp++] = token.code;

        ptr = ( char * ) source_ptr;

        while ( *ptr && *ptr != '\n' && *ptr != ';' )
            if ( *ptr == '\\' && *( ptr + 1 ) == '\n' )
            {
                *ptr = ' ';
                ptr++;
                *ptr = ' ';
                ptr++;
                line_count++;
            }
            else
                ptr++;

        c = *ptr;
        *ptr = '\0';

        actual_line_count = line_count;
        actual_sources = sources;

        token_init( source_ptr, current_file );

        identifiers_as_strings = 1;
        res = compile_expresion( 0, 0, 1, TYPE_DWORD );
        identifiers_as_strings = 0;
        /*
        printf ("exp: asignation: [%d] call: [%d] lvalue: [%d] constant: [%d] value: [%d] lvalue: [%f] type: [%d]\n",
                      res.asignation,
                      res.call,
                      res.lvalue,
                      res.constant,
                      res.value,
                      res.fvalue,
                      typedef_base(res.type));
        */
        if ( sources != actual_sources ) token_endfile();
        *ptr = c;
        source_ptr = ptr;
        line_count = actual_line_count;

        SKIP_SPACES_UNTIL_LF_AND_COUNT_LINES;
        if ( *source_ptr && *source_ptr != '\n' )
        {
            compile_warning( "extra tokens at end of #if directive" );
            SKIP_ALL_UNTIL_LF_AND_COUNT_LINES;
        }
        if ( *source_ptr == '\n' ) line_count--;

        use_saved = 0;
        if ( !res.constant ) compile_error( MSG_CONSTANT_EXP );
        if ( !res.value )
        {
            preprocessor_jumpto( id_else, id_endif );

            SKIP_SPACES_UNTIL_LF_AND_COUNT_LINES;
            if ( *source_ptr && *source_ptr != '\n' )
            {
                if ( token.code == id_else ) compile_warning( "extra tokens at end of #else directive" );
                else if ( token.code == id_endif ) compile_warning( "extra tokens at end of #endif directive" );
                SKIP_ALL_UNTIL_LF_AND_COUNT_LINES;
            }
            if ( *source_ptr == '\n' ) line_count--;
        }

        return;
    }

    /* #else */

    if ( token.code == id_else )
    {
        if ( !prepro_sp ) compile_error( "#else without #if" );

        int stck_code = prepro_stack[--prepro_sp];

        if ( prepro_sp < 0 ||
                (
                    stck_code != id_if &&
                    stck_code != id_ifdef &&
                    stck_code != id_ifndef
                )
           )
        {
            if ( stck_code == id_else )
            {
                compile_error( "#else after #else" );
            }
            else
            {
                compile_error( "#else without #if" );
            }
        }
        prepro_stack[prepro_sp++] = token.code;

        SKIP_SPACES_UNTIL_LF_AND_COUNT_LINES;
        if ( *source_ptr && *source_ptr != '\n' )
        {
            compile_warning( "extra tokens at end of #else directive" );
            SKIP_ALL_UNTIL_LF_AND_COUNT_LINES;
        }
        if ( *source_ptr == '\n' ) line_count--;

        preprocessor_jumpto( id_endif, 0 );

        SKIP_SPACES_UNTIL_LF_AND_COUNT_LINES;
        if ( *source_ptr && *source_ptr != '\n' )
        {
            compile_warning( "extra tokens at end of #endif directive" );
            SKIP_ALL_UNTIL_LF_AND_COUNT_LINES;
        }
        if ( *source_ptr == '\n' ) line_count--;
        return;
    }

    /* #endif */

    if ( token.code == id_endif )
    {
        int stck_code = prepro_stack[--prepro_sp];

        if ( prepro_sp < 0 || (
                    stck_code != id_else &&
                    stck_code != id_if &&
                    stck_code != id_ifdef &&
                    stck_code != id_ifndef ) ) compile_error( "#endif without #if" );

        SKIP_SPACES_UNTIL_LF_AND_COUNT_LINES;
        if ( *source_ptr == '\n' ) line_count--;
        return;
    }

    /* Unknown preprocessor directive */
    compile_error( MSG_UNKNOWN_PREP );
}