Example #1
0
int compile_varspace( VARSPACE * n, segment * data, int additive, int copies, int padding, VARSPACE ** collision, int alignment, int duplicateignore )
{
    int i, j, total_count, last_count = 0 ;
    int base_offset = data->current ;
    int total_length ;
    int size, count ;
    int code ;
    expresion_result res ;
    VARIABLE * var ;
    int unsigned_prefix = 0;
    int signed_prefix = 0;

    BASETYPE basetype = TYPE_UNDEFINED ;
    TYPEDEF type, typeaux;
    segment * segm = NULL ;
    PROCDEF * proc = NULL;

    /* Backup vars */
    BASETYPE basetypeb = TYPE_UNDEFINED ;
    TYPEDEF typeb;
    segment * segmb = NULL ;

    /* Initialize some stuffs */

    type = typedef_new( TYPE_UNDEFINED ) ;
    typeb = typedef_new( TYPE_UNDEFINED ) ;

    for ( ;; )
    {
        if ( n->reserved == n->count ) varspace_alloc( n, 16 ) ;

        if ( alignment && ( n->size % alignment ) > 0 )
        {
            int extra = alignment - ( n->size % alignment );
            if ( n->reserved <= n->count + extra )
            {
                varspace_alloc( n, extra + 16 );
            }
            if ( data->reserved <= data->current + extra )
            {
                segment_alloc( data, extra + 16 );
            }
            n->size += extra;
            data->current += extra;
        }

        token_next() ;

        /* Se salta comas y puntos y coma */

        if ( token.type == NOTOKEN ) break ;

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

        if ( token.code == identifier_comma )
        {
            basetype = basetypeb ;
            type = typeb ;

            segm = segmb ;

            continue ;
        }
        else if ( token.code == identifier_semicolon )
        {
            basetype = TYPE_UNDEFINED ;
            set_type( &type, TYPE_UNDEFINED ) ;

            basetypeb = basetype ;
            typeb = type ;

            segm = NULL ;
            proc = NULL ;

            continue ;
        }
        else if ( token.code == identifier_end )
        {
            break ;
        }

        /* "Unsigned" */

        if ( token.code == identifier_unsigned )
        {
            unsigned_prefix = 1;
            token_next();
        }
        else if ( token.code == identifier_signed )
        {
            signed_prefix = 1;
            token_next();
        }

        /* Tipos de datos básicos */

        if ( token.code == identifier_dword )
        {
            basetype = signed_prefix ? TYPE_INT : TYPE_DWORD ;
            signed_prefix = unsigned_prefix = 0;
            token_next() ;
        }
        else if ( token.code == identifier_word )
        {
            basetype = signed_prefix ? TYPE_SHORT : TYPE_WORD ;
            signed_prefix = unsigned_prefix = 0;
            token_next() ;
        }
        else if ( token.code == identifier_byte )
        {
            basetype = signed_prefix ? TYPE_SBYTE : TYPE_BYTE ;
            signed_prefix = unsigned_prefix = 0;
            token_next() ;
        }
        else if ( token.code == identifier_int )
        {
            basetype = unsigned_prefix ? TYPE_DWORD : TYPE_INT;
            signed_prefix = unsigned_prefix = 0;
            token_next() ;
        }
        else if ( token.code == identifier_short )
        {
            basetype = unsigned_prefix ? TYPE_WORD : TYPE_SHORT;
            signed_prefix = unsigned_prefix = 0;
            token_next() ;
        }
        else if ( token.code == identifier_char )
        {
            basetype = TYPE_CHAR ;
            token_next() ;
        }
        else if ( token.code == identifier_float )
        {
            basetype = TYPE_FLOAT ;
            token_next() ;
        }
        else if ( token.code == identifier_string )
        {
            basetype = TYPE_STRING ;
            token_next() ;
        }
        else
        {
            if ( !proc && ( proc = procdef_search( token.code ) ) )    /* Variables tipo proceso, Splinter */
            {
                basetype = TYPE_INT ;
                token_next();
            }
            else
            {
                if (
                    token.type == IDENTIFIER &&
                    token.code >= reserved_words &&
                    !segment_by_name( token.code ) )
                {
                    int code = token.code;
                    token_next();
                    if ( token.type == IDENTIFIER && token.code >= reserved_words )
                    {
                        proc = procdef_new( procdef_getid(), code );
                        basetype = TYPE_INT ;
                    }
                    else
                    {
                        token_back();
                    }
                }
            }
        }

        if ( signed_prefix || unsigned_prefix ) compile_error( MSG_INVALID_TYPE );
        if ( basetype != TYPE_STRUCT ) type = typedef_new( basetype ) ;
        if ( basetype == TYPE_UNDEFINED ) type = typedef_new( TYPE_INT ) ;

        /* Tipos de datos definidos por el usuario */
        if ( basetype != TYPE_STRUCT && ( segm = segment_by_name( token.code ) ) )
        {
            basetype = TYPE_STRUCT ;
            type = * typedef_by_name( token.code ) ;
            token_next() ;
        }

        if ( token.type == IDENTIFIER && token.code == identifier_struct )
        {
            type.chunk[0].type = TYPE_STRUCT ;
            type.chunk[0].count = 1 ;
            type.depth = 1 ;
            token_next() ;
            segm = 0 ;
        }

        basetypeb = basetype ;
        typeb = type ;
        segmb = segm ;

        /* Tipos de datos derivados */
        while ( token.type == IDENTIFIER && ( token.code == identifier_pointer || token.code == identifier_multiply ) )
        {
            type = typedef_enlarge( type ) ;
            type.chunk[0].type = TYPE_POINTER ;
            basetype = TYPE_POINTER ;
            segm = NULL ;
            token_next() ;
        }

        /* Nombre del dato */

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

        if ( token.code < reserved_words )
        {
            if ( proc ) compile_error( MSG_VARIABLE_ERROR );
            token_back() ;
            break ;
        }

        if (( var = varspace_search( n, token.code ) ) )
        {
            if ( duplicateignore )
            {
                int skip_all_until_semicolon = 0;
                int skip_equal = 0;

                if ( debug ) compile_warning( 0, MSG_VARIABLE_REDECLARE ) ;

                for ( ;; )
                {
                    token_next() ;

                    /* Se salta todo hasta el puntos y coma o en el end o la coma si no hay asignacion */

                    if ( token.type == NOTOKEN ) break ;

                    if ( token.type == IDENTIFIER )
                    {
                        if ( !skip_equal && token.code == identifier_equal )
                        {
                            skip_all_until_semicolon = 1;
                            continue;
                        }

                        if ( !skip_all_until_semicolon && token.code == identifier_comma ) break;
                        if ( token.code == identifier_semicolon ) break ;
                        if ( token.code == identifier_end ) break ;
                    }
                }
                token_back();
                continue;
            }
            else
                compile_error( MSG_VARIABLE_REDECLARE ) ;
        }

        /* (2006/11/19 19:34 GMT-03:00, Splinter - [email protected]) */
        if ( collision )
            for ( i = 0; collision[i];i++ )
                if ( varspace_search( collision[i], token.code ) ) compile_error( MSG_VARIABLE_REDECLARE ) ;
        /* (2006/11/19 19:34 GMT-03:00, Splinter - [email protected]) */

        if ( constants_search( token.code ) ) compile_error( MSG_CONSTANT_REDECLARED_AS_VARIABLE ) ;

        code = token.code ;
        n->vars[n->count].code = token.code ;
        n->vars[n->count].offset = data->current;

        /* Non-additive STRUCT; use zero-based member offsets */

        if ( !additive ) n->vars[n->count].offset -= base_offset;

        token_next() ;

        /* Compila una estructura no predefinida */

        if ( !segm && typedef_is_struct( type ) )
        {
            VARSPACE * members ;

            type.chunk[0].count = 1 ;
            count = 1 ;
            while ( token.type == IDENTIFIER && token.code == identifier_leftb )
            {
                res = compile_expresion( 1, 0, 0, TYPE_INT ) ;
                if ( !typedef_is_integer( res.type ) ) compile_error( MSG_INTEGER_REQUIRED ) ;
                count *= res.value + 1 ;
                type = typedef_enlarge( type ) ;
                type.chunk[0].type  = TYPE_ARRAY ;
                type.chunk[0].count = res.value + 1 ;
                token_next() ;
                if ( token.type != IDENTIFIER || token.code != identifier_rightb ) compile_error( MSG_EXPECTED, "]" ) ;
                token_next() ;
            }
            token_back() ;

            /* Da la vuelta a los índices [10][5] -> [5][10] */

            for ( i = 0 ; i < type.depth ; i++ ) if ( type.chunk[i].type != TYPE_ARRAY ) break ;
            i--;
            for ( j = 0 ; j <= i ; j++ ) typeaux.chunk[ j ] = type.chunk[ i - j ];
            for ( j = 0 ; j <= i ; j++ ) type.chunk[ j ]    = typeaux.chunk[ j ];

            members = ( VARSPACE * )calloc( 1, sizeof( VARSPACE ) ) ;
            if ( !members )
            {
                fprintf( stdout, "compile_varspace: out of memory\n" ) ;
                exit( 1 ) ;
            }
            varspace_init( members ) ;

            size = compile_varspace( members, data, 0, count, 0, NULL, 0, duplicateignore ) ;

            type.varspace = members ;

            token_next() ;
            if ( token.type == IDENTIFIER && token.code == identifier_equal )
            {
                i = data->current ;
                data->current = n->vars[n->count].offset ;
                compile_struct_data( members, data, count, 0 );
                data->current = i ;
            }
            else
            {
                token_back() ;
            }

            for ( i = 0 ; i < members->stringvar_count ; i++ )
                varspace_varstring( n, members->stringvars[i] ) ;

            n->size += typedef_size( type ) ;
            n->vars[n->count].type = type ;
            n->count++ ;

            continue ;  /* No ; */

        }
        else if ( token.type == IDENTIFIER && token.code == identifier_leftb ) /* Compila un array */
        {
            total_count = 1 ;

            while ( token.type == IDENTIFIER && token.code == identifier_leftb )
            {
                if ( type.depth == MAX_TYPECHUNKS ) compile_error( MSG_TOO_MANY_AL ) ;

                type = typedef_enlarge( type ) ;
                type.chunk[0].type = TYPE_ARRAY ;

                token_next() ;
                if ( token.type == IDENTIFIER && token.code == identifier_rightb )
                {
                    type.chunk[0].count = 0 ;
                    if ( total_count != 1 ) compile_error( MSG_VTA ) ;
                    total_count = 0 ;
                    last_count = 0 ;
                }
                else
                {
                    token_back() ;
                    res = compile_expresion( 1, 0, 0, TYPE_DWORD ) ;
                    if ( !total_count ) compile_error( MSG_VTA ) ;
                    total_count *= res.value + 1 ;
                    last_count = res.value + 1 ;
                    type.chunk[0].count = res.value + 1 ;
                    token_next() ;
                    if ( token.type != IDENTIFIER || token.code != identifier_rightb ) compile_error( MSG_EXPECTED, "]" ) ;
                }

                token_next() ;
            }

            /* Da la vuelta a los índices [10][5] -> [5][10] */

            for ( i = 0 ; i < type.depth ; i++ ) if ( type.chunk[i].type != TYPE_ARRAY ) break ;
            i--;
            for ( j = 0 ; j <= i ; j++ ) typeaux.chunk[ j ] = type.chunk[ i - j ];
            for ( j = 0 ; j <= i ; j++ ) type.chunk[ j ]    = typeaux.chunk[ j ];

            if ( segm && token.type == IDENTIFIER && token.code == identifier_equal )
            {
                for ( i = 0 ; i < total_count ; i++ ) segment_add_from( data, segm ) ;
                i = data->current ;
                data->current = n->vars[n->count].offset ;
                compile_struct_data( type.varspace, data, typedef_count( type ), 0 );

                if ( !type.chunk[0].count )
                    type.chunk[0].count = ( data->current - i ) / typedef_size( typeb );
                else
                    data->current = i; /* Solo si ya habia sido alocada */

            }
            else if ( token.type == IDENTIFIER && token.code == identifier_equal )
            {
                /* if (basetype == TYPE_UNDEFINED) basetype = TYPE_INT; */
                i = compile_array_data( n, data, total_count, last_count, &basetype ) ;
                assert( basetype != TYPE_UNDEFINED ) ;
                set_type( &type, basetype ) ;
                if ( total_count == 0 )
                {
                    type.chunk[0].count = i;
                }
                else if ( i < total_count )
                {
                    for ( ; i < total_count; i++ )
                    {
                        if ( basetype == TYPE_STRING ) varspace_varstring( n, data->current ) ;
                        segment_add_as( data, 0, basetype ) ;
                    }
                }
            }
            else if ( segm )
            {
                int string_offset = 0, j;

                if ( total_count == 0 ) compile_error( MSG_EXPECTED, "=" ) ;

                for ( i = 0; i < total_count; i++ )
                {
                    segment_add_from( data, segm ) ;
                    for ( j = 0; j < type.varspace->stringvar_count; j++ )
                        varspace_varstring( n, type.varspace->stringvars[j] + string_offset );
                    string_offset += type.varspace->size;
                }
                token_back() ;
            }
            else
            {
                if ( basetype == TYPE_UNDEFINED )
                {
                    basetype = TYPE_INT;
                    set_type( &type, basetype ) ;
                }

                if ( type.chunk[0].count == 0 ) compile_error( MSG_EXPECTED, "=" ) ;

                for ( i = 0; i < total_count; i++ )
                {
                    if ( basetype == TYPE_STRING ) varspace_varstring( n, data->current ) ;
                    segment_add_as( data, 0, basetype ) ;
                }
                token_back() ;
            }
        }
        else if ( segm && token.type == IDENTIFIER && token.code == identifier_equal ) /* Compila una asignación de valores por defecto */
        {
            segment_add_from( data, segm ) ;
            i = data->current ;
            data->current = n->vars[n->count].offset ;
            if ( !additive ) data->current += base_offset;
            compile_struct_data( type.varspace, data, 1, 0 );
            data->current = i ;

        }
        else if ( token.type == IDENTIFIER && token.code == identifier_equal )
        {
            res = compile_expresion( 1, 0, 0, basetype ) ;

            if ( basetype == TYPE_UNDEFINED )
            {
                basetype = typedef_base( res.type ) ;
                if ( basetype == TYPE_UNDEFINED ) compile_error( MSG_INCOMP_TYPE ) ;
                set_type( &type, basetype ) ;
            }

            if ( basetype == TYPE_FLOAT )
            {
                segment_add_as( data, *( int * )&res.fvalue, basetype ) ;
            }
            else
            {
                if ( basetype == TYPE_STRING ) varspace_varstring( n, data->current ) ;
                segment_add_as( data, res.value, basetype ) ;
            }

        }
        else if ( !segm ) /* Asigna valores por defecto (0) */
        {
            if ( basetype == TYPE_UNDEFINED )
            {
                basetype = TYPE_INT;
                set_type( &type, basetype ) ;
            }

            if ( basetype == TYPE_STRING ) varspace_varstring( n, data->current ) ;
            segment_add_as( data, 0, basetype ) ;
            token_back() ;

        }
        else
        {
            if ( typedef_is_struct( type ) )
                for ( i = 0 ; i < type.varspace->stringvar_count ; i++ )
                    varspace_varstring( n, type.varspace->stringvars[i] + n->size );
            segment_add_from( data, segm ) ;
            token_back() ;
        }

        n->size += typedef_size( type ) ;
        n->vars[n->count].type = type ;

        /* Variables tipo proceso, asigno varspace al tipo. Splinter */
        if ( proc ) n->vars[n->count].type.varspace = proc->pubvars;

        n->count++ ;

        token_next() ;

        if ( token.type == IDENTIFIER && token.code == identifier_comma )
        {
            token_back() ;
            continue ;
        }

        if ( token.type == IDENTIFIER && token.code == identifier_semicolon )
        {
            token_back() ;
            continue ;
        }

        compile_error( MSG_EXPECTED, ";" ) ;
        token_back() ;
        break ;
    }

    if ( padding && ( data->current % padding ) > 0 )
    {
        padding -= data->current % padding;
        data->current += padding;
        n->size += padding;

        if ( data->reserved <= data->current )
            segment_alloc( data, data->reserved - data->current + 32 );
    }

    n->last_offset = data->current ;
    total_length = data->current - base_offset ;

    /* n->size *= copies ; */
    while ( copies-- > 1 )
    {
        int i ;

        for ( i = 0 ; i < n->stringvar_count ; i++ )
        {
            if ( n->stringvars[i] >= base_offset && n->stringvars[i] < base_offset + total_length )
            {
                varspace_varstring( n, n->stringvars[i] - base_offset + data->current ) ;
            }
        }

        segment_copy( data, base_offset, total_length ) ;
        base_offset += total_length ;
    }

    return total_length ;
}
Example #2
0
int main( int argc, char *argv[] )
{
    time_t curtime;
    struct tm *loctime;
    int value, code;
    char * d, *d1;

    char * sourcefile = 0;
    char basepathname[__MAX_PATH] = "";
    char dcbname[__MAX_PATH] = "";
    char stubname[__MAX_PATH] = "";
    char importname[__MAX_PATH] = "";
    char compilerimport[__MAX_PATH] = "";
    int i, j;
    char *ptr;

    /* get my executable name */
    ptr = argv[0] + strlen( argv[0] );
    while ( ptr > argv[0] && ptr[-1] != '\\' && ptr[-1] != '/' ) ptr-- ;
    appexename = strdup( ptr );

    /* get executable full pathname  */
    appexefullpath = getfullpath( argv[0] );
    if ( ( !strchr( argv[0], '\\' ) && !strchr( argv[0], '/' ) ) && !file_exists( appexefullpath ) )
    {
        char *p = whereis( appexename );
        if ( p )
        {
            char * tmp = calloc( 1, strlen( p ) + strlen( appexename ) + 2 );
            free( appexefullpath );
            sprintf( tmp, "%s/%s", p, appexename );
            appexefullpath = getfullpath( tmp );
            free( tmp );
        }
    }

    /* get pathname of executable */
    ptr = strstr( appexefullpath, appexename );
    appexepath = calloc( 1, ptr - appexefullpath + 1 );
    strncpy( appexepath, appexefullpath, ptr - appexefullpath );

    printf( BGDC_VERSION "\n"
            "Bennu Game Development Compiler\n"
            "\n"
            "Copyright (c) 2006-2016 SplinterGU (Fenix/BennuGD)\n"
            "Copyright (c) 2002-2006 Fenix Team (Fenix)\n"
            "Copyright (c) 1999-2002 José Luis Cebrián Pagüe (Fenix)\n"
            "\n" );

    /* Default lang to EN */
    strcpy( langinfo, "EN" );
    /* LANG detect */
#ifdef WIN32
    GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SABBREVCTRYNAME, langinfo, 64 );
    strlwr( langinfo );
#else
    if ( getenv( "LANG" ) != NULL && strlen( getenv( "LANG" ) ) >= 2 )
        strcpy( langinfo, getenv( "LANG" ) );
#endif
    langinfo[2] = 0;

    srand( time( NULL ) );

    /* build error messages list */
    err_buildErrorTable();

    init_c_type();
    identifier_init();
    constants_init();
    string_init();
    compile_init();

    mainproc = procdef_new( procdef_getid(), identifier_search_or_add( "MAIN" ) ) ;

    /* Init vars */

    char tmp_version[ 32 ];
    sprintf( tmp_version, "\"%s\"", VERSION );
    add_simple_define( "COMPILER_VERSION", tmp_version );
    add_simple_define( "__VERSION__", tmp_version );

    curtime = time( NULL ); /* Get the current time. */
    loctime = localtime( &curtime ); /* Convert it to local time representation. */

    strftime( timebuff, sizeof( timebuff ), "%Y/%m/%d", loctime );
    value = string_new( timebuff );
    code = identifier_search_or_add( "__DATE__" ) ;
    constants_add( code, typedef_new( TYPE_STRING ), value ) ;

    strftime( timebuff, sizeof( timebuff ), "%H:%M:%S", loctime );
    value = string_new( timebuff );
    code = identifier_search_or_add( "__TIME__" ) ;
    constants_add( code, typedef_new( TYPE_STRING ), value ) ;
/*
    value = string_new( VERSION );
    code = identifier_search_or_add( "__VERSION__" ) ;
    constants_add( code, typedef_new( TYPE_STRING ), value ) ;
    code = identifier_search_or_add( "COMPILER_VERSION" ) ;
    constants_add( code, typedef_new( TYPE_STRING ), value ) ;
*/
    strcpy( _tmp, VERSION );
                d = strchr( _tmp, '.' ); *d = '\0'; add_simple_define( "__BGD__", _tmp );
    d1 = d + 1; d = strchr(   d1, '.' ); *d = '\0'; add_simple_define( "__BGD_MINOR__", d1 );
    d1 = d + 1;                                     add_simple_define( "__BGD_PATCHLEVEL__", d1 );

    memset( &dcb, 0, sizeof( dcb ) );

    core_init();
    sysproc_init();

    /* Get command line parameters */

    for ( i = 1 ; i < argc ; i++ )
    {
        if ( argv[i][0] == '-' )
        {
            if ( !strcmp( argv[i], "--pedantic" ) )
            {
                autodeclare = 0 ;
                continue;
            }

            if ( !strcmp( argv[i], "--libmode" ) )
            {
                libmode = 1 ;
                continue;
            }

            j = 1;
            while ( argv[i][j] )
            {
                if ( argv[i][j] == 'd' )
                {
                    if ( argv[i][j + 1] >= '0' && argv[i][j + 1] <= '9' )
                    {
                        debug = atoi( &argv[i][j + 1] );
                    }
                    else
                    {
                        debug = 1;
                    }
                }

                if ( argv[i][j] == 'o' )
                {
                    if ( argv[i][j + 1] )
                        strncpy( dcbname, &argv[i][j + 1], sizeof( dcbname ) );
                    else if ( argv[i + 1] && argv[i + 1][0] != '-' )
                        strncpy( dcbname, argv[++i], sizeof( dcbname ) );
                    break;
                }

                if ( argv[i][j] == 'c' ) dos_chars = 1;

                if ( argv[i][j] == 'a' ) autoinclude = 1;

                if ( argv[i][j] == 'g' ) dcb_options |= DCB_DEBUG;

                if ( argv[i][j] == 'p' ) autodeclare = 0 ;

                if ( argv[i][j] == 's' )
                {
                    /* -s "stub": Use a stub */

                    if ( argv[i][j + 1] )
                        strncpy( stubname, &argv[i][j + 1], __MAX_PATH );
                    else if ( argv[i + 1] && argv[i + 1][0] != '-' )
                        strncpy( stubname, argv[++i], __MAX_PATH );
                    break;
                }

                if ( argv[i][j] == 'f' )
                {
                    /* -f "file": Embed a file to the DCB */

                    if ( argv[i][j + 1] )
                        dcb_add_file( &argv[i][j + 1] );
                    else while ( argv[i + 1] )
                        {
                            if ( argv[i + 1][0] == '-' ) break;
                            dcb_add_file( argv[i + 1] );
                            i++;
                        }
                    break;
                }

                if ( argv[i][j] == 'i' )
                {
                    /* -i "path": add a file to the path for include files */

                    if ( argv[i][j + 1] == 0 )
                    {
                        if ( i == argc - 1 )
                        {
                            printf( MSG_DIRECTORY_MISSING "\n" );
                            exit( 1 );
                        }
                        file_addp( argv[i + 1] );
                        i++;
                        break;
                    }
                    file_addp( &argv[i][j + 1] );
                    break;
                }

                if ( argv[i][j] == 'l' )
                {
                    /* -lLANG:  Set the language for errors and messages */

                    if ( argv[i][j + 1] == 0 )
                    {
                        if ( i != argc - 1 )
                        {
                            strcpy( langinfo, argv[i + 1] );
                        }
                        i++;
                        break;
                    }
                    strcpy( langinfo, &argv[i][j + 1] );
                    break;
                }

                if ( argv[i][j] == 'D' )
                {
                    char * macro = NULL ;
                    char * text = NULL ;

                    /* -D<macro>=<text> */

                    if ( argv[i][j + 1] )
                    {
                        macro = strdup( &argv[i][j + 1] );
                    }
                    else
                    {
                        if ( argv[i + 1][0] == '-' ) break;
                        macro = strdup( argv[i + 1] );
                        i++;
                    }

                    if (( text = strchr( macro, '=' ) ) )
                    {
                        * text = '\0';
                        text++;
                    }
                    else
                    {
                        text = "";
                    }

                    add_simple_define( macro, text );
                    free( macro );
                    break;
                }

                if ( argv[i][j] == 'C' )
                {
                    if ( argv[i][j + 1] == 'a' ) autodeclare = 1 ;
                    break;
                }

                if ( argv[i][j] == 'L' )
                {
                    int r = 1;
                    char * f;
                    if ( argv[i][j + 1] )
                        r = dcb_load_lib( ( f = &argv[i][j + 1] ) );
                    else if ( argv[i + 1] && argv[i + 1][0] != '-' )
                    {
                        r = dcb_load_lib( ( f = argv[i + 1] ) );
                        i++;
                    }

                    switch ( r )
                    {
                        case    0:
                                printf( "ERROR: %s doesn't exist or isn't version DCB compatible\n", f ) ;
                                exit( -1 );

                        case    -1:
                                printf( "ERROR: %s isn't 7.10 DCB version, you need a 7.10 version or greater for use this feature\n", f ) ;
                                exit( -1 );
                    }
                    break;
                }

                j++;
            }
        }
        else
        {
/*
            if ( sourcefile )
            {
                printf( MSG_TOO_MANY_FILES "\n" );
                return 0;
            }
*/
            char * p, * pathend = NULL;

            sourcefile = argv[i];
            p = main_path = strdup( argv[i] );
            while ( p && *p )
            {
                if ( *p == ':' || *p == '\\' || *p == '/' ) pathend = p;
                p++;
            }
            if ( pathend )
            {
                *( pathend + 1 ) = '\0';
                file_addp( main_path );
            }
            else
            {
                free( main_path );
                main_path = getcwd(malloc(__MAX_PATH), __MAX_PATH);
                strcat(main_path, PATH_SEP);
            }

            /* Files names */

            strcpy( basepathname, sourcefile );
            REMOVE_EXT( basepathname );

            /* Default compiler imports */
            strcpy( compilerimport, argv[0] );
#ifdef WIN32
            REMOVE_EXT( compilerimport );
#endif
            strcat( compilerimport, ".imp" );
            import_files( compilerimport );
            strcat( compilerimport, "ort" ); /* name.import */
            import_files( compilerimport );

            /* Project imports */
            strcpy( importname, basepathname ); strcat( importname, ".imp" );
            import_files( importname );

            strcat( importname, "ort" ); /* name.import */
            import_files( importname );

            /* Load Main Source File */
            load_file( sourcefile );

            if ( !dcbname[0] )
            {
                strcpy( dcbname, basepathname ); strcat( dcbname, !libmode ? ".dcb" : ".dcl" );
            }
        }
    }

    if ( !sourcefile )
    {
        printf( MSG_USING
                MSG_OPTION_D
                MSG_OPTIONS
                MSG_LICENSE, argv[0] );
        return 0;
    }

    compile_program();

    if ( stubname[0] != 0 )
    {
        if ( !file_exists( stubname ) )
        {
#ifdef WIN32
            char exepath[__MAX_PATH];

            GetModuleFileName( NULL, exepath, sizeof( exepath ) );
            PathRemoveFileSpec( exepath );
            strcat( exepath, "\\" );
            memmove( stubname + strlen( exepath ), stubname, strlen( stubname ) + 1 );
            memcpy( stubname, exepath, strlen( exepath ) );
#else
            const char * ptr = argv[0] + strlen( argv[0] );
            while ( ptr > argv[0] && *ptr != '\\' && *ptr != '/' ) ptr--;
            if ( *ptr == '\\' || *ptr == '/' ) ptr++;
            if ( ptr > argv[0] )
            {
                memmove( stubname + ( ptr - argv[0] ), stubname, strlen( stubname ) + 1 );
                memcpy( stubname, argv[0], ptr - argv[0] );
            }
#endif
            if ( !file_exists( stubname ) )
            {
#ifdef WIN32
                strcat( stubname, ".exe" );
                if ( !file_exists( stubname ) )
                {
#endif
                    compile_error( "Can't open stub file %s", stubname );
#ifdef WIN32
                    return -1;
                }
#endif

            }
        }

        REMOVE_EXT( dcbname );
#ifdef WIN32
        strcat( dcbname, ".exe" );
#endif
        dcb_save( dcbname, dcb_options, stubname );
    }
    else
    {
        dcb_save( dcbname, dcb_options, NULL );
    }

    /* destroy error messages list */
    err_destroyErrorTable();

    return 1;
}