translat.c

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

C
779
字号
        FreeMem( s );
    }
}


/*
 * Create the '.exp' file
 */
void CreateExp( OPT_STORAGE *cmdOpts, char * name )
/*************************************************/
{
    char *              newstr;
    OPT_STRING *        optStr;
    char *              p;
    char *              tmp;
    char                expname[_MAX_PATH];
    char                drive[_MAX_DRIVE];
    char                dir[_MAX_DIR];
    char                fname[_MAX_FNAME];

    /*** Replace the '.lib' extension with '.exp' ***/
    _splitpath( name, drive, dir, fname, NULL );
    _makepath( expname, drive, dir, fname, ".exp" );

    exp = fopen( expname, "w" );
    if( exp == NULL ) {
        FatalError( "Cannot create file: %s ", expname );
    }

    optStr = comment;
    while( optStr != NULL ) {
        fprintf( exp, "OPTION DESCRIPTION %s\n", optStr->data );
        optStr = optStr->next;
    }
    del_string(&comment); // don't need it any more

    if( cmdOpts->name ) {
        if( (*cmdOpts->name_value->data == '\'') ) {
            tmp = cmdOpts->name_value->data + 1; /* skip leading ' */
            tmp[ strlen(tmp)-1 ] = '\0';         /* smite trailing ' */
        } else {
            tmp = cmdOpts->name_value->data;
        }
        newstr = PathConvert( tmp, '\'' );
        fprintf( exp, "NAME %s\n", newstr );
        FreeMem( newstr );
    }

    if( base ) {
        fprintf( exp, "OPTION OFFSET=%s\n", base->data );
    }
    del_string(&base); // don't need it any more

    if( heap ) {
        p = strchr( heap->data, ',' );
        if( p == NULL ) {               /* /HEAP:reserve */
            fprintf( exp, "OPTION HEAPSIZE=%s\n", heap->data );
        } else {                        /* /HEAP:reserve,commit */
            *p = '\0';
            fprintf( exp, "OPTION HEAPSIZE=%s\n", heap->data );
            p++;
            fprintf( exp, "COMMIT HEAP=%s\n", p );
        }
    }
    del_string(&heap); // don't need it any more

    if( stack ) {
        p = strchr( stack->data, ',' );
        if( p == NULL ) {               /* /STACK:reserve */
            fprintf( exp, "OPTION STACK=%s\n", stack->data );
        } else {                        /* /STACK:reserve,commit */
            *p = '\0';
            fprintf( exp, "OPTION STACK=%s\n", stack->data );
            p++;
            fprintf( exp, "COMMIT STACK=%s\n", p );
        }
    }
    del_string(&stack); // don't need it any more

    if( internaldllname ) {
        newstr = DupQuoteStrMem( internaldllname->data, '\'' );
        fprintf( exp, "OPTION MODNAME=%s\n",newstr );
        FreeMem( newstr );
    }
    del_string(&internaldllname); // don't need it any more

    if( stub ) {
        if( (*stub->data == '\'') ) {
            tmp = stub->data + 1;             /* skip leading ' */
            tmp[ strlen(tmp)-1 ] = '\0';      /* smite trailing ' */
        } else {
            tmp = stub->data;
        }
        newstr = PathConvert( tmp, '\'' );
        fprintf( exp, "OPTION STUB=%s\n", newstr );
        FreeMem( newstr );
    }
    del_string(&stub); // don't need it any more

    if( version ) {
        fprintf( exp, "OPTION VERSION=%s\n", version->data );
    }
    del_string(&version); // don't need it any more
}


/*
 * Creates import library entry from export statement
 */
static char *ImportEntry( char *export, char *dll_name )
/*******************************************************/
{
    char *              internal_name=NULL;
    char *              ordinal=NULL;
    char *              the_rest=NULL;
    char *              entry_name=NULL;
    char *              export_copy;
    char *              p=NULL;
    int                 len=9; /* 7 is for all the '.' and '+' required +1 */

    len+=strlen(dll_name);
    export_copy = DupStrMem(export);
    p=strchr(export_copy+1,'\'');
    if (export_copy[0]!='\'' || p==NULL) Zoinks(); // the entry_name must be in quotes
    p++;
    if (*p!='\0') { /* there is something after the entry_name */
        entry_name = p; // char after the entry_name
        p=strchr(p,'=');
        if (p!=NULL) { /* internal_name found */
            *p='\0';
            internal_name=(p+1);
            p=strchr(internal_name,' ');
            if (p!=NULL) { /* there is something after the internal_name */
                *p='\0';
                the_rest=(p+1);
            }
        }

        p=strchr(entry_name,'.');
        if (p!=NULL) { /* ordinal found */
            *p='\0';
            ordinal=(p+1);
            if (internal_name==NULL) {
                p=strchr(ordinal,' ');
                if (p!=NULL) { /* there is something after the ordinal */
                    *p='\0';
                    the_rest=(p+1);
                }
            }
            len+=strlen(ordinal);
        }

        if ((internal_name==NULL) && (ordinal==NULL)) {
            p=strchr(entry_name,' ');
            if (p!=NULL) { /* there is something after the entry_name */
                *p='\0';
                the_rest=(p+1);
            }
        }

        *entry_name='\0'; /* separate the entry name from the rest of the export directive */
    }
    entry_name = export_copy;

    if( internal_name == NULL ) {
        internal_name = MatchFuzzy( entry_name );
    } else {
        internal_name = MatchFuzzy( internal_name );
    }

    if (the_rest) {
        strupr( the_rest);
    }

    /***  do the '.exp'  file entry  ***/
    if( internal_name != NULL ) {
        fprintf( exp, "EXPORT %s", entry_name );
        if (ordinal) {
            fprintf( exp, ".%s", ordinal );
        }
        fprintf( exp, "=%s", internal_name );
        if (the_rest) {
            fprintf( exp, " %s", the_rest );
        }
        fprintf( exp, "\n");
    } else {
        fprintf( exp, "EXPORT %s\n", export );
    }


    /***  do the import library entry ***/

    if (the_rest && strstr(the_rest,"PRIVATE")) {
        FreeMem( export_copy );
        return NULL;
    }

    len+=strlen(entry_name);

    if (internal_name!=NULL) {
        len+=strlen(internal_name);
    }

    p = AllocMem(len);
    *p = '\0';
    strcat (p,"++");
    if (internal_name!=NULL) {
        strcat(p, internal_name);
    } else {
        strcat(p, entry_name);
    }
    strcat( p, ".'" );
    strcat( p, dll_name );
    strcat( p, "'" );
    if (internal_name!=NULL) {
        strcat( p, ".." );
        strcat(p, entry_name);
    }
    if (ordinal!=NULL) {
        strcat( p, "." );
        strcat(p,ordinal);
    }
    FreeMem( export_copy );
    return p;
}




/*
 * Parse librarian options.
 */
static void lib_opts( OPT_STORAGE *cmdOpts, CmdLine *cmdLine )
/************************************************************/
{
    char *              newstr=NULL;
    char *              p;
    OPT_STRING *        optStr;
    char                dllfilename[_MAX_PATH];
    char                drive[_MAX_DRIVE];
    char                dir[_MAX_DIR];
    char                fname[_MAX_FNAME];

    if ( cmdOpts->def ) {
        if ( cmdOpts->out ) {
            newstr = VerifyDot(cmdOpts->out_value->data);
        } else {
            newstr = VerifyDot(cmdOpts->def_value->data);
            newstr = ReallocMem( newstr, strlen(newstr)+4 );
            if (strchr(newstr,'.')==NULL) Zoinks();
            strcpy(strchr(newstr,'.'),".lib");
        }
        AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "%s", newstr );
        CreateExp( cmdOpts, newstr );
        _splitpath( newstr, drive, dir, fname, NULL );  /* .dll extension */
        _makepath( dllfilename, drive, dir, fname, ".dll" );
        if (cmdOpts->export) {
            init_fuzzy();
            optStr = cmdOpts->export_value;
            while( optStr != NULL ) {
                p = ImportEntry( optStr->data, dllfilename );
                if (p) {
                    AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "%s", p);
                    FreeMem(p);
                }
                optStr = optStr->next;
            }

            if (exp) fclose(exp);
            FiniFuzzy();
        }else {
            FatalError( "/EXPORT option not specified!" );
        }
    }else if( cmdOpts->list ) {
        if( cmdOpts->list_value != NULL ) {
            newstr = VerifyDot(cmdOpts->list_value->data);
            AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "/l=%s", newstr );
        }
        get_library(cmdOpts, cmdLine);
    } else if ( cmdOpts->extract ) {
        get_library(cmdOpts, cmdLine);
        if( cmdOpts->out) {
            Warning( "Ignoring unsupported option /OUT following /EXTRACT." );
            Warning( "'%s' will be used as output name.",cmdOpts->extract_value->data );
            cmdOpts->out=0;
        }
        newstr = VerifyDot(cmdOpts->extract_value->data);
        AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "*%s", newstr );

    } else {
        if ( cmdOpts->out ) {
            newstr = VerifyDot(cmdOpts->out_value->data);
            AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "%s", newstr );
        } else {
            get_library(cmdOpts, cmdLine);
        }
        get_files(cmdLine);
        optStr = cmdOpts->remove_value;
        while( optStr != NULL ) {
            newstr = VerifyDot(optStr->data);
            AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "-%s", newstr );
            optStr = optStr->next;
        }

    }
    if (newstr!=NULL) FreeMem(newstr);

}


/*
 * Activate options which are always to be turned on.
 */
static void default_opts( OPT_STORAGE *cmdOpts, CmdLine *cmdLine )
/****************************************************************/
{
    if( !cmdOpts->list && !cmdOpts->nowopts ) {
        AppendCmdLine( cmdLine, LIB_OPTS_SECTION, "/q/b" );
    }
}


/*
 * Add any options meant for the Watcom tools.
 */
static void watcom_opts( OPT_STORAGE *cmdOpts, CmdLine *cmdLine )
/***************************************************************/
{
    OPT_STRING *        curr;

    if( cmdOpts->passwopts ) {
        for( curr=cmdOpts->passwopts_value; curr!=NULL; curr=curr->next ) {
            AppendCmdLine( cmdLine, LIB_OPTS_SECTION, curr->data );
        }
    }
}


/*
 * Case-insensitive version of strstr.
 */
static char *stristr( const char *str, const char *substr )
/*********************************************************/
{
    size_t              strLen;
    size_t              substrLen;
    int                 i, maxi;
    char                ch;

    substrLen = strlen( substr );
    if( substrLen == 0 )  return( (char*)str );

    strLen = strlen( str );
    maxi = strLen - substrLen + 1;
    ch = substr[0];

    for( i=0; i<maxi; i++ ) {
        if( str[i] == ch ) {
            if( !strnicmp( str+i, substr, substrLen ) ) {
                return( (char*)str+i );
            }
        }
    }

    return( NULL );
}


/*
 * 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 ***/
    if( cmdOpts->nologo ) {
        QuietModeMessage();
    } else {
        BannerMessage();
    }

    /*** Parse everything ***/
    default_opts( cmdOpts, cmdLine );
    def_file_opts( cmdOpts );
    unsupported_opts( cmdOpts );
    lib_opts( cmdOpts, cmdLine );
    watcom_opts( cmdOpts, cmdLine );
}

⌨️ 快捷键说明

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