wcl.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,055 行 · 第 1/3 页
C
1,055 行
/****************************************************************************
*
* 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: C/C++ Compile and Link utility.
*
****************************************************************************/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#ifndef __UNIX__
#include <direct.h>
#else
#include <dirent.h>
#endif
#include <process.h>
#include <malloc.h>
#include <conio.h>
#include "cmdlhelp.h"
#include "clcommon.h"
#include "banner.h"
#undef _BANEXTRA
#define _BANEXTRA _BANEXSHORT
#ifdef WCLAXP
#define WCLNAME "wclaxp" /* Name of Compile and Link Utility*/
#define CC "wccaxp" /* Open Watcom C compiler */
#define CCXX "wppaxp" /* Open Watcom C++ compiler */
#define WCLENV "WCLAXP" /* name of environment variable */
#define STACKSIZE "8192" /* default stack size */
#define _NAME_ "C/C++ Alpha AXP "
#elif defined( WCLPPC )
#define WCLNAME "wclppc" /* Name of Compile and Link Utility*/
#define CC "wccppc" /* Open Watcom C compiler */
#define CCXX "wppppc" /* Open Watcom C++ compiler */
#define WCLENV "WCLPPC" /* name of environment variable */
#define STACKSIZE "8192" /* default stack size */
#define _NAME_ "C/C++ PowerPC "
#elif defined( WCLMPS )
#define WCLNAME "wclmps" /* Name of Compile and Link Utility*/
#define CC "wccmps" /* Open Watcom C compiler */
#define CCXX "wppmps" /* Open Watcom C++ compiler */
#define WCLENV "WCLMPS" /* name of environment variable */
#define STACKSIZE "8192" /* default stack size */
#define _NAME_ "C/C++ MIPS "
#elif defined( WCL386 )
#define WCLNAME "wcl386" /* Name of Compile and Link Utility*/
#define CC "wcc386" /* Open Watcom C compiler */
#define CCXX "wpp386" /* Open Watcom C++ compiler */
#define WCLENV "WCL386" /* name of environment variable */
#define STACKSIZE "8192" /* default stack size */
#define _NAME_ "C/C++32 "
#else
#define WCLNAME "wcl" /* Name of Compile and Link Utility*/
#define CC "wcc" /* Open Watcom C compiler */
#define CCXX "wpp" /* Open Watcom C++ compiler */
#define WCLENV "WCL" /* name of environment variable */
#define STACKSIZE "4096" /* default stack size */
#define _NAME_ "C/C++16 "
#endif
#ifdef __UNIX__
#define PATH_SEP_STR "/"
#else
#define PATH_SEP_STR "\\"
#endif
#define LINK "wlink" /* Open Watcom linker */
#define TEMPFILE "@__wcl__.lnk" /* temporary linker directive file */
static char *Word; /* one parameter */
static char *SystemName; /* system to link for */
static char Files[MAX_CMD]; /* list of filenames from Cmd */
static char Resources[MAX_CMD]; /* list of resources from Cmd */
static char CC_Opts[MAX_CMD]; /* list of compiler options from Cmd */
static char CC_Path[_MAX_PATH]; /* path name for wcc.exe */
static char PathBuffer[_MAX_PATH];/* buffer for path name of tool */
static char *Link_Name; /* Temp_Link copy if /fd specified */
static char *Temp_Link; /* temporary linker directive file */
/* Temp_Link concurrent usages clash */
static struct directives *Directive_List; /* linked list of directives */
static char *StackSize = NULL; /* size of stack */
static char DebugFlag = 0; /* debug info wanted */
static char Conventions; /* 'r' for -3r or 's' for -3s */
static char Switch_Chars[4]; /* valid switch characters */
static int via_environment = FALSE;
/*
* Static function prototypes
*/
static int Parse( char *Cmd );
#if defined( __UNIX__ )
#define _dos_switch_char() '-'
#elif defined( __OS2__ ) || defined( __NT__ )
#define _dos_switch_char() '/'
#else
extern int _dos_switch_char( void );
#endif
#undef pick
#define pick( code, english ) english
extern const char *WclMsgs[] = {
#include "wclmsg.h"
};
static const char *EnglishHelp[] = {
#include "wclhelp.h"
NULL
};
static void initialize_Flags( void )
/**********************************/
{
struct flags const zero_flags = { 0 };
Flags = zero_flags;
Flags.math_8087 = 1;
}
static int handle_environment_variable( const char *env )
/*******************************************************/
// This is an adaptation of code in sdk/rc/rc/c/param.c
{
typedef struct EnvVarInfo {
struct EnvVarInfo *next;
char *varname;
// An anonymous copy of Word and *env is appended here
} EnvVarInfo;
EnvVarInfo *info;
static EnvVarInfo *stack = 0; // Needed to detect recursion.
unsigned argbufsize;
size_t varlen; // size to hold varname copy.
int result; // Parse Result.
for( info = stack; info != NULL; info = info->next ) {
#if !defined( __UNIX__ )
if( stricmp( Word, info->varname ) == 0 ) // Case-insensitive
#else
if( strcmp( Word, info->varname ) == 0 ) // Case-sensitive
#endif
{
PrintMsg( WclMsgs[RECURSIVE_ENVIRONMENT_VARIABLE], Word );
return( 1 );
}
}
argbufsize = strlen( env ) + 1; // inter-parameter spaces map to 0
varlen = strlen( Word ) + 1; // Copy taken to detect recursion.
info = MemAlloc( sizeof( *info ) + argbufsize + varlen );
info->next = stack;
stack = info; // push info on stack
info->varname = (char *)info + sizeof( *info );
strcpy( info->varname, Word );
result = Parse( strcpy( info->varname + varlen, env ) );
stack = info->next; // pop stack
free( info );
return( result );
}
/*
* makeTmpEnv() and killTmpEnv() ar adapted from synonyms in wmake/c/mexec.c.
* They are simpler because support for recursion is not needed.
*/
static void *makeTmpEnv( char *arg )
/**********************************/
/*
* Copy arg into an environment var if possible. If succeeds, then changes
* arg to just "@WCLxxxxx", and returns non-zero. Otherwise leaves
* arg alone and returns zero.
*/
{
int wcl_index;
char buf[20]; /* "WCLxxxxx=" + '\0' = 11 + room for FmtStr */
size_t len;
size_t buflen;
char *env;
wcl_index = 1;
while( sprintf( buf, "WCL%d", wcl_index ), getenv( buf ) != NULL ) {
++wcl_index;
}
len = strlen( arg );
buflen = strlen( buf );
if( len < 4 + buflen ) /* need room for " @WCLxxxxx" */
return( 0 );
/* "WCLxxxxx=" + arg + '\0' */
env = MemAlloc( len + buflen + 2 );
sprintf( env, "%s=%s", buf, arg );
if( putenv( env ) != 0 )
return( 0 );
if( !Flags.be_quiet )
PrintMsg( " set %s\n", env );
sprintf( arg, " @%s", buf );
return( env );
}
static void killTmpEnv( char *env )
/*********************************/
{
char const * const equals = strchr( env, '=' );
if( equals ) {
size_t const chars = 1 + (size_t)(equals - env);
char * const never_free = MemAlloc( 1 + chars );
strncpy( never_free, env, chars );
never_free[chars] = 0;
if( !Flags.be_quiet )
PrintMsg( " set %s\n", never_free );
if( putenv( never_free ) == 0 )
free( env );
free( never_free ); /* Actually OK */
}
}
void print_banner( void )
/***********************/
{
static int done;
if( done ) return;
puts( banner1w( _NAME_ "Compile and Link Utility", _WCL_VERSION_ ) );
puts( banner2( "1988" ) );
puts( banner3 );
puts( banner3a );
done = 1;
}
static char *SkipSpaces( char *ptr )
/************************************/
{
while( *ptr == ' ' || *ptr == '\t' ) { /* 16-mar-91 */
ptr++;
}
return( ptr );
}
static void MakeName( char *name, char *ext )
/*********************************************/
{
/* If the last '.' is before the last path seperator character */
if( strrchr( name, '.' ) <= strpbrk( name, PATH_SEP_STR ) ) {
strcat( name, ext );
}
}
static void Usage( void )
/************************/
{
char const **list;
char const *p;
int lines_printed;
unsigned int i, n;
auto char buf[82];
#ifndef __UNIX__
int const paging = isatty( fileno( stdout ) );
int const height = 24; /* Number of lines assumed on screen */
#endif
print_banner();
lines_printed = 4;
list = EnglishHelp;
while( *list ) {
memset( buf, ' ', 80 );
if( **list == '[' ) { /* title to be centered */
i = strlen( *list );
strcpy( &buf[38 - i / 2], *list );
++list;
for( n = 0; list[n]; ++n ) { /* count number in list */
if( *list[n] == '[' ) break;
}
n = (n + 1) / 2; /* half way through list */
#ifndef __UNIX__
if( paging && lines_printed != 0 && lines_printed >= height ) {
fputs( WclMsgs[ PRESS_ANY_KEY_TO_CONTINUE ], stdout );
fflush( stdout );
getch();
puts( "" );
lines_printed = 0;
}
#endif
puts( buf );
lines_printed++;
for( ;; ) {
memset( buf, ' ', 80 );
p = *list;
if( p == NULL ) break;
for( i = 0; *p; ) buf[i++] = *p++;
p = list[n];
if( p != NULL && *p != '[' ) {
for( i = 38; *p; ) buf[i++] = *p++;
}
buf[i] = '\0';
puts( buf );
lines_printed++;
#ifndef __UNIX__
if( paging && lines_printed != 0 && lines_printed >= height ) {
fputs( WclMsgs[ PRESS_ANY_KEY_TO_CONTINUE ], stdout );
fflush( stdout );
getch();
puts( "" );
lines_printed = 0;
}
#endif
p = list[n];
if( p == NULL ) break;
if( *p == '[' ) break;
list[n] = NULL; /* indicate already printed */
++list;
}
list = &list[n];
} else {
puts( *list );
lines_printed++;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?