translat.c

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

C
779
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Translate Microsoft LIB to Watcom options.
*
****************************************************************************/


#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cmdline.h"
#include "deffile.h"
#include "error.h"
#include "file.h"
#include "fuzzy.h"
#include "lib.h"
#include "message.h"
#include "memory.h"
#include "pathconv.h"
#include "translat.h"
#include "system.h"

#define UNSUPPORTED_STR_SIZE    512

static char *   stristr( const char *str, const char *substr );

static FILE *           exp = NULL; /* '.exp' file containing export entries for the linker */

static OPT_STRING *     comment = NULL;
static OPT_STRING *     base = NULL;
static OPT_STRING *     heap = NULL;
static OPT_STRING *     stack = NULL;
static OPT_STRING *     internaldllname = NULL;
static OPT_STRING *     stub = NULL;
static OPT_STRING *     version = NULL;


/*
 * Add one more unsupported option to optStr.
 */
static void append_unsupported( char *optStr, char *opt )
/*******************************************************/
{
    if( optStr[0] != '\0' ) {
        strcat( optStr, " /" );
    } else {
        strcat( optStr, "/" );
    }
    strcat( optStr, opt );
}


/*
 * Parse unsupported options.
 */
static void unsupported_opts( OPT_STORAGE *cmdOpts )
/**************************************************/
{
    char                opts[UNSUPPORTED_STR_SIZE];

    /*** Build a string listing all unsupported options that were used ***/
    opts[0] = '\0';
    if( cmdOpts->debugtype   )  append_unsupported( opts, "DEBUGTYPE"   );
    if( cmdOpts->import      )  append_unsupported( opts, "IMPORT"      );
    if( cmdOpts->include     )  append_unsupported( opts, "INCLUDE"     );
    if( cmdOpts->mac         )  append_unsupported( opts, "MAC"         );
    if( cmdOpts->nodefaultlib)  append_unsupported( opts, "NODEFAULTLIB");
    if( cmdOpts->subsystem   )  append_unsupported( opts, "SUBSYSTEM"   );
    if( cmdOpts->verbose     )  append_unsupported( opts, "VERBOSE"     );

    /*** If an unsupported option was used, give a warning ***/
    if( opts[0] != '\0' ) {
        UnsupportedOptsMessage( opts );
    }

    if (cmdOpts->machine) {
        if ( (stricmp("IX86",cmdOpts->machine_value->data)!=0) &&
             (stricmp("I386",cmdOpts->machine_value->data)!=0) &&
             (stricmp("APX",cmdOpts->machine_value->data)!=0) &&
             (stricmp("ALPHA",cmdOpts->machine_value->data)!=0) ) {
            Warning("%s target platform is not supported",cmdOpts->machine_value->data);
        }
    }
}


/*
 * Add another string to an OPT_STRING.
 */
static void add_string( OPT_STRING **p, char *str )
/*************************************************/
{
    OPT_STRING *        buf;
    OPT_STRING *        curElem;

    /*** Make a new list item ***/
    buf = AllocMem( sizeof(OPT_STRING) + strlen(str) );
    strcpy( buf->data, str );
    buf->next = NULL;

    /*** Put it at the end of the list ***/
    if( *p == NULL ) {
        *p = buf;
    } else {
        curElem = *p;
        while( curElem->next != NULL )  curElem = curElem->next;
        curElem->next = buf;
    }
}


/*
 * Parse a .def file if necessary.
 */
static void def_file_opts( OPT_STORAGE *cmdOpts )
/***********************************************/
{
    DefInfo *           info;
    StringList *        strList;

    if( cmdOpts->def ) {
        #ifdef __TARGET_AXP__
            info = ParseDefFile( cmdOpts->def_value->data,
                                 !cmdOpts->nofuzzy );
        #else
            info = ParseDefFile( cmdOpts->def_value->data );
        #endif
        if( info != NULL ) {
            strList = info->exports;
            while( strList != NULL ) {
                cmdOpts->export=1;
                add_string( &cmdOpts->export_value, strList->str );
                strList = strList->next;
            }

            strList = info->description;
            while( strList != NULL ) {
                add_string( &comment, strList->str );
                strList = strList->next;
            }

            if( info->name != NULL ) {
                add_string( &cmdOpts->name_value, info->name );
                cmdOpts->name = 1;
            }


            if( info->baseAddr != NULL ) {
                add_string( &base, info->baseAddr );
            }

            if( info->heapsize != NULL ) {
                add_string( &heap, info->heapsize );
            }

            if( info->stacksize != NULL ) {
                add_string( &stack, info->stacksize );
            }

            if( info->internalDllName != NULL ) {
                add_string( &internaldllname, info->internalDllName );
            }

            if( info->stub != NULL ) {
                add_string( &stub, info->stub );
            }

            if( info->version != NULL ) {
                add_string( &version, info->version );
            }

            FreeDefInfo(info);
        } else {
            FatalError( "Error parsing %s -- aborting",
                        cmdOpts->def_value->data );
        }
    }
}


/*
 * Get first library or object file from the list. WLIB will use its name as its main library.
 */
static void get_library(OPT_STORAGE *cmdOpts, CmdLine *cmdLine )
/**************************************************************/
{
    char *              filename;
    char *              filecopy;
    int                 fileType;
    char *              newfilename;
    char *              tempfilename;
    int                 quotes_found=0;

    filename = GetNextFile( &fileType, TYPE_LIB_FILE, TYPE_OBJ_FILE, TYPE_INVALID_FILE );
    if( filename != NULL ) {
        if (fileType==TYPE_OBJ_FILE){
            if ((cmdOpts->list) || (cmdOpts->extract)) {
                for (;;) {
                    if( stristr( filename, ".obj" )  ==  NULL ) {
                        AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "%s", filename );
                        FreeMem(filename);
                        break;
                    } else {
                        FreeMem(filename);
                        filename = GetNextFile( &fileType, TYPE_LIB_FILE, TYPE_OBJ_FILE, TYPE_INVALID_FILE );
                    }
                    if (filename==NULL) FatalError("no library or object files specified!");
                }
            } else {
                /*** Strip quotes from filename  and the extension ***/
                filecopy=DupStrMem(filename);
                newfilename = ReallocMem( filename, strlen(filename)+4 );
                if( *newfilename == '"' ) {
                    tempfilename = newfilename + 1;                     /* skip leading " */
                    quotes_found=1;
                } else {
                    tempfilename = newfilename;
                }
                if (strchr(tempfilename,'.')==NULL) Zoinks();
                *strchr(tempfilename,'.') = '\0';
                /*** Append '.lib' at the end of filename and add quotes if needed ***/
                if (quotes_found) {
                    tempfilename = DupQuoteStrMem(strcat(tempfilename,".lib"),'"');
                } else {
                    tempfilename = DupStrMem(strcat(tempfilename,".lib"));
                }
                FreeMem( newfilename );
                AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "%s", tempfilename );
                FreeMem( tempfilename );
                AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "-+%s", filecopy );
            }
        } else {
            AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "%s", filename );
            FreeMem(filename);
        }
    } else {
        FatalError("no library or object files specified!");
    }

}


/*
 * Get the rest of library files and object files from the list.
 */
static void get_files(CmdLine *cmdLine )
/**************************************/
{
    char *              filename;
    int                 fileType;

    for( ;; ) {
        filename = GetNextFile( &fileType, TYPE_LIB_FILE, TYPE_OBJ_FILE, TYPE_INVALID_FILE );
        if( filename == NULL ) break;
        AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "-+%s", filename );
        FreeMem( filename );
    }

    /*** Ignore all '.rbj', '.rs', and '.res' files ***/
    for( ;; ) {
        filename = GetNextFile( &fileType, TYPE_RES_FILE, TYPE_RBJ_FILE,
                                TYPE_RS_FILE, TYPE_INVALID_FILE );
        if( filename == NULL )  break;
        Warning( "Ignoring resource file '%s'", filename );
        FreeMem( filename );
    }
}


/*
 * Appends '.' to a filename without extension ie. 'my_file' becomes 'my_file.'
 */
static char *VerifyDot( char *filename )
/************************************/
{
    char *              newfilename;
    char *              tempfilename;
    char *              filecopy;
    int                 quotes_found=0;

    filecopy = DupStrMem(filename);
    if (strchr(filename,'.')==NULL) {
        /*** Strip quotes from filename ***/
        newfilename = ReallocMem( filecopy, strlen(filecopy)+2 );
        if( *newfilename == '"' ) {
            tempfilename = newfilename + 1;                     /* skip leading " */
            tempfilename[ strlen(tempfilename)-1 ] = '\0';      /* smite trailing " */
            quotes_found=1;
        } else {
            tempfilename = newfilename;
        }
        /*** Append '.' at the end of filename and add quotes if needed ***/
        if (quotes_found) {
            filecopy = DupQuoteStrMem(strcat(tempfilename,"."),'"');
        } else {
            filecopy = DupStrMem(strcat(tempfilename,"."));
        }
        FreeMem( newfilename );
    }
    return filecopy;
}


/*
 * Called by InitFuzzy when an error occurs.
 */
static int fuzzy_init_callback( const char *filename )
/****************************************************/
{
    Warning( "Cannot extract external symbols from '%s' -- fuzzy name matching may not work",
             filename );
    return( 1 );
}


/*
 * Initialize fuzzy linking.
 */
static void init_fuzzy( void )
/****************************/
{
    unsigned            count;
    char *              filename;
    char *              newstr;
    char                ext[_MAX_EXT];
    char **             objsvector;

    /*** Get the object file names into an array ***/
    count = 0;
    objsvector = AllocMem( (count+1) * sizeof(char*) );
    for( ;; ) {
        filename = GetNextFile( NULL, TYPE_OBJ_FILE, TYPE_INVALID_FILE );
        if( filename == NULL )  break;
        newstr = PathConvert( filename, '\'' );

        /*** Skip .res files ***/
        _splitpath( newstr, NULL, NULL, NULL, ext );
        if( !stricmp( ext, ".res" ) ) {
            FreeMem( newstr );
            continue;
        }

        objsvector[count] = newstr;
        count++;
        objsvector = ReallocMem( objsvector, (count+1) * sizeof(char*) );
    }
    objsvector[count] = NULL;

    /*** Ok, now tell the fuzzy module to initialize itself ***/
    InitFuzzy( (const char**)objsvector, NULL, NULL, fuzzy_init_callback );
    FreeMem( objsvector );
}


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

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

⌨️ 快捷键说明

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