translat.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 888 行 · 第 1/2 页

C
888
字号
            libpathsvector[count-1] = DupStrMem( start );
            start = end;
        }
        FreeMem( newstr );
    }

    /*** Get the default library paths into the 'libpathsvector' array ***/
    envvar = getenv( "WATCOM" );
    if( envvar != NULL ) {
        count += 2;
        libpathsvector = ReallocMem( libpathsvector, (count+1) * sizeof(char*) );

        len = strlen( envvar ) + strlen( NT_LIBDIR_SUFFIX ) + 1;
        libpathsvector[count-2] = AllocMem( len );
        sprintf( libpathsvector[count-2], "%s%s", envvar, NT_LIBDIR_SUFFIX );

        len = strlen( envvar ) + strlen( LIBDIR_SUFFIX ) + 1;
        libpathsvector[count-1] = AllocMem( len );
        sprintf( libpathsvector[count-1], "%s%s", envvar, LIBDIR_SUFFIX );
    }
    libpathsvector[count] = NULL;

    /*** Ok, now do something with these arrays ***/
    InitFuzzy( (const char**)objsvector, (const char**)libsvector,
               (const char**)libpathsvector, fuzzy_init_callback );
    FreeMem( objsvector );
    FreeMem( libsvector );
    for( count=0; libpathsvector[count]!=NULL; count++ ) {
        FreeMem( libpathsvector[count] );
    }
    FreeMem( libpathsvector );
}


/*
 * Determine the name of the executable, and place it in the given buffer.
 */
static void get_executable_name( const OPT_STORAGE *cmdOpts, char *firstObj,
                                 char *executable )
/**************************************************************************/
{
    char                drive[_MAX_DRIVE];
    char                dir[_MAX_DIR];
    char                fname[_MAX_FNAME];

    if( cmdOpts->out ) {
        strcpy( executable, cmdOpts->out_value->data );
    } else {
        _splitpath( firstObj, drive, dir, fname, NULL );
        if( !cmdOpts->dll ) {
            _makepath( executable, drive, dir, fname, ".exe" );
        } else {
            _makepath( executable, drive, dir, fname, ".dll" );
        }
    }
}


/*
 * Destroy an OPT_STRING.
 */
static void del_string( OPT_STRING **p )
/**************************************/
{
    OPT_STRING *        s;

    while( *p != NULL ) {
        s = *p;
        *p = s->next;
        FreeMem( s );
    }
}


/*
 * Parse linker options.
 */
static void linker_opts( struct XlatStatus *status,
                         const OPT_STORAGE *cmdOpts, CmdLine *cmdLine )
/*********************************************************************/
{
    OPT_STRING *        optStr;
    OPT_STRING *        objs = NULL;
    OPT_STRING *        libs = NULL;
    char *              p;
    char *              newstr;
    char *              filename;
    int                 fileType;
    int                 numFiles;
    char *              firstObj = NULL;
    char                executable[_MAX_PATH];
    char *              tmp;
    char *              envvar;

    /*** Process all object file names ***/
    for( numFiles=0; ; numFiles++ ) {
        filename = GetNextFile( &fileType, TYPE_OBJ_FILE, TYPE_INVALID_FILE );
        if( filename == NULL )  break;
        if( cmdOpts->export || cmdOpts->entry ) {
            add_string( &objs, filename );
        }
        newstr = PathConvert( filename, '\'' );
        if( firstObj == NULL )  firstObj = newstr;
        if( numFiles == 0 ) {
            AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "FILE {" );
        }
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, " %s", newstr );
    }
    if( numFiles != 0 ) {
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "}" );
    } else {
        Warning( "No object files specified" );
        FatalError( "Nothing to do!" );
    }

    /*** Process all library file names ***/
    for( ;; ) {
        filename = GetNextFile( &fileType, TYPE_LIB_FILE, TYPE_INVALID_FILE );
        if( filename == NULL )  break;
        if( cmdOpts->export || cmdOpts->entry ) {
            add_string( &libs, filename );
        }
        newstr = PathConvert( filename, '\'' );
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "LIBRARY %s", newstr );
    }

    /*** Process all '.exp' file names ***/
    for( ;; ) {
        filename = GetNextFile( &fileType, TYPE_EXP_FILE, TYPE_INVALID_FILE );
        if( filename == NULL )  break;
        status->exp=1;
        newstr = PathConvert( filename, '\'' );
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "@ %s", newstr );
    }

    /*** Process all '.rbj' and '.rs' file names ***/
    for( ;; ) {
        filename = GetNextFile( &fileType, TYPE_RBJ_FILE, TYPE_RS_FILE, TYPE_INVALID_FILE );
        if( filename == NULL )  break;
        newstr = PathConvert( filename, '\'' );
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION RESOURCE %s", newstr );
    }

    /*** Process the LIB environment variable ***/
    envvar = getenv( "LIB" );
    if( envvar != NULL ) {
        newstr = PathConvert( envvar, '\'' );
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "LIBPATH %s", newstr );
    }

    if( cmdOpts->incremental ) {
        if( !stricmp( cmdOpts->incremental_value->data, "yes" ) ) {
            if( cmdOpts->release ) {
                Warning( "Ignoring /INCREMENTAL due to /RELEASE" );
            } else {
                if( !cmdOpts->_10x ) {
                    AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION incremental" );
                }
            }
        }
    }

    if( cmdOpts->align ) {
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION alignment=%u",
                          cmdOpts->align_value );
    }

    if( cmdOpts->base ) {
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION offset=%s",
                          cmdOpts->base_value->data );
    }

    optStr = cmdOpts->comment_value;
    while( optStr != NULL ) {
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION description %s",
                          optStr->data );
        optStr = optStr->next;
    }

    if( cmdOpts->debug ) {
        if( cmdOpts->_10x ) {
            AppendCmdLine( cmdLine, LINK_SYSTEM_SECTION, "DEBUG dwarf" );
        } else {
            AppendCmdLine( cmdLine, LINK_SYSTEM_SECTION, "DEBUG dwarf all" );
        }
    }

    optStr = cmdOpts->defaultlib_value;
    while( optStr != NULL ) {
        newstr = PathConvert( optStr->data, '\'' );
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "LIBRARY %s", newstr );
        optStr = optStr->next;
    }

    /*** Initialize fuzzy linking if necessary ***/
    if( cmdOpts->export || cmdOpts->entry ) {
        if( !cmdOpts->nofuzzy ) {
            init_fuzzy( objs, libs, cmdOpts->defaultlib_value );
        }
    }

    /*** Handle the /entry option ***/
    if( cmdOpts->entry ) {
        if( cmdOpts->nofuzzy ) {
            AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION,
                              "REFERENCE %s OPTION start=%s",
                              cmdOpts->entry_value->data,
                              cmdOpts->entry_value->data );
        } else {
            p = MatchFuzzy( cmdOpts->entry_value->data );
            if( p != NULL ) {
                AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION,
                                  "REFERENCE %s OPTION start=%s", p, p );
                FreeMem( p );
            } else {
                AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION,
                                  "REFERENCE %s OPTION start=%s",
                                  cmdOpts->entry_value->data,
                                  cmdOpts->entry_value->data );
            }
        }
    }

    /*** Handle export directives ***/
    if( cmdOpts->export ) {
        if( cmdOpts->nofuzzy ) {
            optStr = cmdOpts->export_value;
            while( optStr != NULL ) {
                AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "EXPORT %s",
                                  optStr->data );
                optStr = optStr->next;
            }
        } else {
            optStr = cmdOpts->export_value;
            while( optStr != NULL ) {
                p = fuzzy_export( optStr->data );
                if( p != NULL ) {
                    AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION,
                                      "EXPORT %s", p );
                    FreeMem( p );
                }
                optStr = optStr->next;
            }
        }
    }
    if( objs != NULL )  del_string( &objs );
    if( libs != NULL )  del_string( &libs );

    /*** Deinitialize fuzzy linking if necessary ***/
    if( cmdOpts->export || cmdOpts->entry ) {
        if( !cmdOpts->nofuzzy ) {
            FiniFuzzy();
        }
    }

    if( cmdOpts->forcemultiple ) {
        AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION redefsok" );
    }
    if( cmdOpts->forceundefined ) {
        AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION undefsok" );
    }

    if( cmdOpts->heap ) {
        p = strchr( cmdOpts->heap_value->data, ',' );
        if( p == NULL ) {               /* /HEAP:reserve */
            AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION heapsize=%s",
                              cmdOpts->heap_value->data );
        } else {                        /* /HEAP:reserve,commit */
            *p = '\0';
            AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION heapsize=%s",
                              cmdOpts->heap_value->data );
            p++;
            AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "COMMIT heap=%s", p );
        }
    }

    if( cmdOpts->implib ) {
        newstr = PathConvert( cmdOpts->implib_value->data, '\'' );
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION implib=%s",
                          newstr );
    }

    optStr = cmdOpts->include_value;
    while( optStr != NULL ) {
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "REFERENCE %s",
                          optStr->data );
        optStr = optStr->next;
    }

    if( cmdOpts->internaldllname ) {
        newstr = DupQuoteStrMem( cmdOpts->internaldllname_value->data, '\'' );
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION modname=%s",
                          newstr );
    }

    if( cmdOpts->map ) {
        if( cmdOpts->map_value != NULL ) {
            AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION map=%s",
                              cmdOpts->map_value->data );
        } else {
            AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION map" );
        }
    }

    if( cmdOpts->nowopts && cmdOpts->nodefaultlib ) {
        AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION nodefaultlibs" );
    }

    if( cmdOpts->opt_level == OPT_opt_level_optref ) {
        AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION eliminate" );
    }

    if( cmdOpts->out ) {
        newstr = PathConvert( cmdOpts->out_value->data, '\'' );
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "NAME %s", newstr );
    }

    if( cmdOpts->release ) {
        AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION checksum" );
    }

    if( cmdOpts->stack ) {
        p = strchr( cmdOpts->stack_value->data, ',' );
        if( p == NULL ) {               /* /STACK:reserve */
            AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION stack=%s",
                              cmdOpts->stack_value->data );
        } else {                        /* /STACK:reserve,commit */
            *p = '\0';
            AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION stack=%s",
                              cmdOpts->stack_value->data );
            p++;
            AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "COMMIT stack=%s", p );
        }
    } else {
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION stack=1M" );
    }

    if( cmdOpts->stub ) {
        if( (*cmdOpts->stub_value->data == '\'') ) {
            tmp = cmdOpts->stub_value->data + 1; /* skip leading ' */
            tmp[ strlen(tmp)-1 ] = '\0';         /* smite trailing ' */
        } else {
            tmp = cmdOpts->stub_value->data;
        }
        newstr = PathConvert( tmp, '\'' );
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION stub=%s",
                          newstr );
    }

    if( cmdOpts->version ) {
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION version=%s",
                          cmdOpts->version_value->data );
    }

    /*** Process all resource file names ***/
    get_executable_name( cmdOpts, firstObj, executable );
    for( ;; ) {
        filename = GetNextFile( &fileType, TYPE_RES_FILE, TYPE_INVALID_FILE );
        if( filename == NULL )  break;
        newstr = PathConvert( filename, '\'' );
        AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION resource=%s", newstr );
    }
}


/*
 * Activate default options.
 */
static void default_opts( struct XlatStatus *status,
                          const OPT_STORAGE *cmdOpts, CmdLine *cmdLine )
{
    if (!cmdOpts->nowopts)
    {
        AppendCmdLine(cmdLine, LINK_OPTS_SECTION, "OPTION quiet");
    } /* if */
} /* default_opts() */


/*
 * Activate options which have been parsed but not yet turned on.
 */
static void merge_opts( struct XlatStatus *status, const OPT_STORAGE *cmdOpts,
                        CmdLine *cmdLine )
/****************************************************************************/
{
    OPT_STRING *curr;
    char       *p;
    char       *system = SYS_NT_CHARMODE;

    if( cmdOpts->subsystem ) {
        p = strchr( cmdOpts->subsystem_value->data, ',' );
        if( p != NULL )  *p = '=';
        p = cmdOpts->subsystem_value->data;

        if( !strnicmp( p, "WINDOWS", 7 )  ||  !strnicmp( p, "NATIVE", 6 ) ) {
            AppendCmdLine(cmdLine, LINK_SYSTEM_SECTION, "RUNTIME windows=4.0");
            system = SYS_NT_WINDOWED;
        } else {
            AppendFmtCmdLine( cmdLine, LINK_SYSTEM_SECTION, "RUNTIME %s", p);
        }
    }

    if( cmdOpts->dll ) {
        AppendFmtCmdLine( cmdLine, LINK_SYSTEM_SECTION, "SYSTEM %s initinstance terminstance", SYS_NT_DLL );
        if( !cmdOpts->implib && !status->exp ) {
            AppendFmtCmdLine( cmdLine, LINK_SYSTEM_SECTION, "OPTION implib" );
        }
    } else {
        AppendFmtCmdLine( cmdLine, LINK_SYSTEM_SECTION, "SYSTEM %s", system );
    }

    /*** Add any options meant for the Watcom tools ***/
    if (cmdOpts->passwopts)
    {
        for (curr = cmdOpts->passwopts_value; curr; curr = curr->next)
        {
            AppendCmdLine(cmdLine, LINK_OPTS_SECTION, curr->data);
        }
    }
}


/*
 * Translate scanned MS options to Watcom options.
 */
void OptionsTranslate( OPT_STORAGE *cmdOpts, CmdLine *cmdLine )
/*************************************************************/
{
    /*** Parse the /nologo switch now so we can print the banner ***/
    init_status( &status );
    if( cmdOpts->nologo ) {
        QuietModeMessage();
    } else {
        BannerMessage();
    }

    /*** Parse everything ***/
    unsupported_opts( cmdOpts );
    default_opts( &status, cmdOpts, cmdLine );
    def_file_opts( cmdOpts );
    linker_opts( &status, cmdOpts, cmdLine );
    merge_opts( &status, cmdOpts, cmdLine );
}

⌨️ 快捷键说明

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