wfl.c

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

C
863
字号
                case 'c':       // compile only
                    if( Word[0] == '\0' ) {
                        Flags.no_link = 1;
                        cmp_option = 0;
                    }
                    break;
                case 'y':
                    if( Word[0] == '\0' ) {
                        cmp_option = 0;
                    }
                    break;
                case 'p':
                    // ignore the /p option - we now only
                    // have a protect-mode compiler
                    if( Word[0] == '\0' ) {
                        cmp_option = 0;
                    }
                    break;
                case 'l':
                    if( ( Word[0] == '=' ) || ( Word[0] == '#' ) ) {
                        Flags.link_for_sys = 1;
                        SystemName = strdup( &Word[1] );
                        cmp_option = 0;
#if _CPU == 8086
                    } else if( stricmp( Word, "r" ) == 0 ) {
                        Flags.link_for_dos = 1;
                        Flags.link_for_os2 = 0;
                        cmp_option = 0;
                    } else if( stricmp( Word, "p" ) == 0 ) {
                        Flags.link_for_os2 = 1;
                        Flags.link_for_dos = 0;
                        cmp_option = 0;
#endif
                    }
                    break;
                case '"':
                    Fputnl( &Word[0], Fp );
                    ++end;      // skip over closing quote
                    cmp_option = 0;
                    break;

                // compiler options that affect the linker

#if _CPU == 386 || _CPU == _AXP || _CPU == _PPC
                case 'b':
                    if( stricmp( Word, "w" ) ) {
                        Flags.default_win = 1;
                    }
                    break;
#endif

                case 'q':
                    if( IsOption( Cmd, len + sizeof(char), "Quiet" ) ) {
                        Flags.quiet = 1;
                    }
                    break;
                case 'd':
                    if( DebugFlag == 0 ) { // not set by -h yet
                        if( strcmp( Word, "1" ) == 0 ) {
                            DebugFlag = 1;
                        } else if( strcmp( Word, "2" ) == 0 ) {
                            DebugFlag = 2;
                        }
                    }
                    break;
                case 'h':
                    if( strcmp( Word, "w" ) == 0 ) {
                        DebugFlag = 3;
                    } else if( strcmp( Word, "c" ) == 0 ) {
                        Flags.do_cvpack = 1;
                        DebugFlag = 4;
                    } else if( strcmp( Word, "d" ) == 0 ) {
                        DebugFlag = 5;
                    }
                    break;
                case 's':
                    if( IsOption( Cmd, len + sizeof( char ), "SYntax" ) ) {
                        Flags.no_link = 1;
                    }
                    break;
#if _CPU == 8086
                case 'w':
                    if( IsOption( Cmd, len + sizeof( char ), "WIndows" ) ) {
                        Flags.windows = 1;
                    }
                    break;
#endif
                default:
                    break;
                }
                // don't add linker-specific options to compiler command line
                if( cmp_option != 0 ) {
                    len = strlen( CmpOpts );
                    CmpOpts[len++] = ' ';
                    CmpOpts[len++] = opt;
                    CmpOpts[len++] = *Cmd;      // keep original case
                    CmpOpts[len] = NULLCHAR;
                    strcat( CmpOpts, Word );
                }
            }
            Cmd = end;
        }
        Cmd = SkipSpaces( Cmd );
    } while( *Cmd != NULLCHAR );
    return( 0 );
}


int     IsOption( char *cmd, int cmd_len, char *opt ) {
//=====================================================

    int         len;

    len = 0;
    for(;;) {
        if( len == cmd_len ) break;
        if( toupper( *cmd ) != toupper( *opt ) ) return( 0 );
        ++cmd;
        ++opt;
        ++len;
    }
    if( *opt == NULLCHAR ) return( 1 );
    if( isupper( *opt ) ) return( 0 );
    return( 1 );
}


static  char    *MakePath( char *path ) {
//=======================================

    char    *p;

    p = strrchr( path ,'\\' );
    if( p != NULL ) {
        p[1] = NULLCHAR;
    } else {
        p = strchr( path, ':' );
        if( p != NULL ) {
            p[1] = NULLCHAR;
        } else {
            *path = NULLCHAR;
        }
    }
    return( strdup( path ) );
}


static  char    *GetName( char *path ) {
//======================================

#ifndef __UNIX__
    static      DIR     *dirp;
    struct      dirent  *direntp;

    if( path != NULL ) {                /* if given a filespec to open,  */
        if( *path == NULLCHAR ) {       /*   but filespec is empty, then */
            closedir( dirp );           /*   close directory and return  */
            return( NULL );             /*   (for clean up after error)  */
        }
        dirp = opendir( path );         /* try to find matching filenames */
        if( dirp == NULL ) {
            PrintMsg( CL_UNABLE_TO_OPEN, path );
            return( NULL );
        }
    }

    while( ( direntp = readdir( dirp ) ) != NULL ) {
        if( ( direntp->d_attr & ATTR_MASK ) == 0 ) {    /* valid file? */
            return( direntp->d_name );
        }
    }
    closedir( dirp );
    return( NULL );
#else
    char *name;
    if ( path == NULL )
            return NULL;
    name = strrchr(path, '/');
    if ( name == NULL )
        name = path;
    else
        name++;
    return ( strdup(name) );
#endif
}


static  int     CompLink( void ) {
//================================

    int         rc;
    char        *p;
    char        *file;
    char        *path;
    int         comp_err;

    if( Flags.quiet ) {
        Fputnl( "option quiet", Fp );
    }
    fputs( DebugOptions[ DebugFlag ], Fp );
    if( Flags.link_for_sys ) {
        fputs( "system ", Fp );
        Fputnl( SystemName, Fp );
    } else {
#if defined( __QNX__ )
        Fputnl( "system qnx", Fp );
#elif _CPU == 386
    #if defined( __OS2__ )
        Fputnl( "system os2v2", Fp );
    #elif defined( __NT__ )
        Fputnl( "system nt", Fp );
    #else
        Fputnl( "system dos4g", Fp );
    #endif
#elif _CPU == 8086
        if( Flags.windows ) {
            Fputnl( "system windows", Fp );
        } else if( Flags.link_for_dos ) {
            Fputnl( "system dos", Fp );
        } else if( Flags.link_for_os2 ) {
            Fputnl( "system os2", Fp );
        } else {
    #if defined( __OS2__ )
            Fputnl( "system os2", Fp );
    #else
            Fputnl( "system dos", Fp );
    #endif
        }
#elif _CPU == _AXP
        Fputnl( "system ntaxp", Fp );
#else
    #error Unknown System
#endif

    }

    comp_err = FALSE;
    p = strtok( Files, " " );   // get first filespec
    while( p != NULL ) {
        strcpy( Word, p );
        MakeName( Word, ".for" );   // if no extension, assume ".for"

        file = GetName( Word );     // get first matching filename
        path = MakePath( Word );    // isolate path portion of filespec
        while( file != NULL ) {     // while more filenames:
            strcpy( Word, path );
            strcat( Word, file );
            strlwr( Word );
            if( strstr( Word, _ObjExtn ) == NULL ) {  // if not object, compile
                if( !Flags.quiet ) {
                    fputs( "        " _CmpName " ", stdout );
                    fputs( Word, stdout );
                    fputs( " ", stdout );
                    puts( CmpOpts );
                    fflush( stdout );
                }
                rc = spawnlp( P_WAIT, CmpPath, _CmpName, Word, CmpOpts, NULL );
                if( rc != 0 ) {
                    comp_err = TRUE;
                    if( ( rc == -1 ) || ( rc == 255 ) ) {
                        PrintMsg( CL_UNABLE_TO_INVOKE_COMPILER );
                        GetName( NULL_STR );
                        return( 1 );
                    } else {
                        PrintMsg( CL_BAD_COMPILE, Word );
                    }
                }
                strcpy( Word, file );
                strlwr( Word );
            }
            p = strrchr( Word, '.' );
            if( p != NULL ) *p = NULLCHAR;

            if( ExeName[0] == '\0' ) {
                fputs( "name ", Fp );
                Fputnl( Word, Fp );
                strcpy( ExeName, Word );
            }
            AddName( Word, Fp );

            file = GetName( NULL );     // get next filename
        }
        p = strtok( NULL, " " );    // get next filespec
    }
    if( Libs[0] != '\0' ) {
        fputs( "library", Fp );
        Fputnl( Libs, Fp );
    }
    fclose( Fp );   // close TempFile

    if( ( ObjList != NULL ) && !Flags.no_link && !comp_err ) {
        FindPath( _LnkExeName, LinkPath );
        if( !Flags.quiet ) {
            puts( NULL_STR );
        }
        fflush( stdout );
        rc = spawnlp( P_WAIT, LinkPath, _LnkName, TempFile, NULL );
        if( rc != 0 ) {
            if( ( rc == -1 ) || ( rc == 255 ) ) {
                PrintMsg( CL_UNABLE_TO_INVOKE_LINKER );
            } else {
                PrintMsg( CL_BAD_LINK );
            }
            return( 2 );    // return 2 to show Temp_File already closed
        }
        if( Flags.do_cvpack ){
            FindPath( _CVPExeName, LinkPath );
            rc = spawnlp( P_WAIT, LinkPath, _CVPName, ExeName, NULL );
            if( rc != 0 ) {
                if( rc == -1  ||  rc == 255 ) {
                    PrintMsg( CL_UNABLE_TO_INVOKE_CVPACK );
                } else {
                    PrintMsg( CL_BAD_CVPACK );
                }
                return( 2 );  /* return 2 to show Temp_File already closed */
            }
        }
    }
    return( 0 );
}


static  void    Fputnl( char *text, FILE *fptr ) {
//================================================

    fputs( text, fptr );
    fputs( "\n", fptr );
}


static  void    MakeName( char *name, char *ext ) {
//=================================================

    if( strrchr( name, '.' ) <= strstr( name, "\\" ) ) {
        strcat( name, ext );
    }
}


static  void    AddName( char *name, FILE *link_fp ) {
//====================================================

    list        *curr_name;
    list        *last_name;
    list        *new_name;
    char        path[_MAX_PATH];
    char        buff1[_MAX_PATH2];
    char        buff2[_MAX_PATH2];
    char        *drive;
    char        *dir;
    char        *fname;
    char        *ext1;
    char        *ext2;
    char        *extension;

    curr_name = ObjList;
    while( curr_name != NULL ) {
        if( stricmp( name, curr_name->filename ) == 0 )  return;
        last_name = curr_name;
        curr_name = curr_name->next;
    }
    new_name = MemAlloc( sizeof( struct list ) );
    if( ObjList == NULL ) {
        ObjList = new_name;
    } else {
        last_name->next = new_name;
    }
    new_name->filename = strdup( name );
    new_name->next = NULL;
    fputs( "file ", link_fp );
    if( ObjName != NULL ) {
        // construct full name of object file from ObjName information
        _splitpath2( ObjName, buff1, &drive, &dir, &fname, &ext1 );
        extension = ext1;
        if( ext1[0] == '\0' ) extension = _ObjExtn;
        if( ( fname[0] == '\0' ) ||
            ( ( fname[0] == '*' ) && ( fname[1] == '\0' ) ) ) {
            _splitpath2( name, buff2, NULL, NULL, &fname, &ext2 );
            if( ext2[0] != '\0' ) extension = ext2;
        }
        _makepath( path, drive, dir, fname, extension );
        name = path;
    }
    Fputnl( name, link_fp );
}


static  void    FindPath( char *name, char *buf ) {
//=================================================

    _searchenv( name, "PATH", buf );
    if( buf[0] == '\0' ) {
        PrintMsg( CL_UNABLE_TO_FIND, name );
        wfl_exit( 1 );
    }
}


void    TOutNL( char *msg ) {
//===========================

    puts( msg );
}


void    TOut( char *msg ) {
//===========================

    fputs( msg, stdout );
}


#define opt( name, bit, flags, actionstr, actionneg, desc ) name, desc, flags

#include "cpopt.h"
#include "optinfo.h"


static  void    Usage( void ) {
//=============================

    char        buff[LIST_BUFF_SIZE+1];

    PrtBanner();
    puts( "" );
    MsgBuffer( CL_USAGE_LINE, buff );
    puts( buff );
    puts( "" );
    ShowOptions( buff );
}

⌨️ 快捷键说明

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