setupinf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,908 行 · 第 1/5 页
C
1,908 行
if( token[ 0 ] == '|' ) { // or together top 2 values
--stack_top;
stack[ stack_top ] = TreeNode( OP_OR, stack[ stack_top ], stack[ stack_top + 1 ] );
} else if( token[ 0 ] == '&' ) { // and together top 2 values
--stack_top;
stack[ stack_top ] = TreeNode( OP_AND, stack[ stack_top ], stack[ stack_top + 1 ] );
} else if( token[ 0 ] == '!' ) { // not top value
stack[ stack_top ] = TreeNode( OP_NOT, stack[ stack_top ], NULL );
} else if( token[0] == '?' ) { // check for file existence
GUIStrDup( &token[1], &p );
++stack_top;
stack[ stack_top ] = TreeNode( OP_EXIST, p, NULL );
} else { // push current value
++stack_top;
stack[ stack_top ] = TreeNode( OP_VAR, NULL, NULL );
stack[ stack_top ]->u.v = GetTokenHandle( token );
}
token = strtok( NULL, " " );
}
// and together whatever is left on stack
tree = stack[ stack_top ];
while( --stack_top >= 0 ) {
tree = TreeNode( OP_AND, tree, stack[ stack_top ] );
}
GUIMemFree( str2 );
return( tree );
}
static bool SameExprTree( tree_node *a, tree_node *b )
/****************************************************/
{
if( a == NULL )
return( b == NULL );
if( b == NULL )
return( a == NULL );
if( a->op != b->op )
return( FALSE );
switch( a->op ) {
case OP_AND:
case OP_OR:
return( SameExprTree( a->u.left, b->u.left ) &&
SameExprTree( a->right, b->right ) );
case OP_NOT:
return( SameExprTree( a->u.left, b->u.left ) );
case OP_EXIST:
return( stricmp( (char*)a->u.left, (char*)b->u.left ) == 0 );
case OP_VAR:
return( (vhandle)a->u.left == (vhandle)b->u.left );
break;
case OP_TRUE:
case OP_FALSE:
return( TRUE );
default:
return( FALSE );
}
}
static void BurnTree( tree_node *tree )
/*************************************/
{
switch( tree->op ) {
case OP_AND:
case OP_OR:
BurnTree( tree->right );
/* fall thru */
case OP_NOT:
BurnTree( tree->u.left );
break;
case OP_EXIST:
GUIMemFree( tree->u.left );
break;
case OP_VAR:
case OP_TRUE:
case OP_FALSE:
break;
}
GUIMemFree( tree );
}
static int NewFileCond( char *str )
/****************************************/
{
tree_node *new;
int num;
new = BuildExprTree( str );
num = SetupInfo.fileconds.num;
while( --num >= 0 ) {
if( SameExprTree( new, FileCondInfo[ num ].cond ) ) {
BurnTree( new );
return( num );
}
}
num = SetupInfo.fileconds.num;
if( !BumpArray( &SetupInfo.fileconds ) ) return( NULL );
FileCondInfo[ num ].cond = new;
FileCondInfo[ num ].one_uptodate = FALSE;
FileCondInfo[ num ].dont_touch = FALSE;
return( num );
}
static vhandle GetTokenHandle( char *p )
/***************************************/
{
if( p == NULL ) {
return( NO_VAR );
} else if( p[0] == '#' ) {
return( atoi( p+1 ) );
} else {
return( AddVariable( p ) );
}
}
int GetOptionVarValue( vhandle var_handle, bool is_minimal )
/**********************************************************/
{
// if( GetVariableIntVal( "_Visibility_Condition_" ) ) {
if( VisibilityCondition ) {
return( VarGetIntVal( var_handle ) );
} else if( IsMagicVar( var_handle ) ) {
// these are special - we always want their "true" values
return( VarGetIntVal( var_handle ) != 0 );
} else if( VarGetIntVal( UnInstall ) ) {
// uninstall makes everything false
return( 0 );
} else if( VarGetIntVal( FullInstall ) &&
VarGetAutoSetCond( var_handle ) != NULL ) {
// fullinstall pretends all options are turned on
return( 1 );
} else if( VarGetIntVal( FullCDInstall ) &&
VarGetAutoSetCond( var_handle ) != NULL ) {
// fullinstallcd pretends all options are turned on except 'HelpFiles'
return( var_handle != HelpFiles );
} else if( is_minimal ) {
// is_minimal makes all file condition variables false
return( FALSE );
} else {
return( VarGetIntVal( var_handle ) != 0 );
}
}
static int EvalExprTree( tree_node *tree, bool is_minimal )
/***************************************************/
{
int value;
char buff[_MAX_PATH];
switch( tree->op ) {
case OP_AND:
value = EvalExprTree( tree->u.left, is_minimal ) &
EvalExprTree( tree->right, is_minimal );
break;
case OP_OR:
value = EvalExprTree( tree->u.left, is_minimal ) |
EvalExprTree( tree->right, is_minimal );
break;
case OP_NOT:
value = !EvalExprTree( tree->u.left, is_minimal );
break;
case OP_EXIST:
ReplaceVars( buff, (char*)tree->u.left );
value = access( buff, F_OK ) == 0;
break;
case OP_VAR:
value = GetOptionVarValue( (vhandle)tree->u.left, is_minimal );
break;
case OP_TRUE:
value = !is_minimal;
break;
case OP_FALSE:
value = 0;
break;
}
return( value );
}
static int DoEvalCondition( char *str, bool is_minimal )
/******************************************************/
{
int value;
tree_node *tree;
tree = BuildExprTree( str );
value = EvalExprTree( tree, is_minimal );
BurnTree( tree );
return( value );
}
int EvalCondition( char *str )
/****************************/
{
return( DoEvalCondition( str, FALSE ) );
}
static void PropagateValue( tree_node *tree, int value )
/***********************************************/
{
vhandle var_handle;
switch( tree->op ) {
case OP_AND:
if( value == 1 ) {
PropagateValue( tree->u.left, 1 );
PropagateValue( tree->right, 1 );
}
break;
case OP_OR:
if( value == 0 ) {
PropagateValue( tree->u.left, 0 );
PropagateValue( tree->right, 0 );
}
break;
case OP_NOT:
PropagateValue( tree->u.left, !value );
break;
case OP_VAR:
if( value != 1 ) break;
var_handle = (vhandle)tree->u.left;
if( VarGetAutoSetCond( var_handle ) != NULL ) {
if( !VarIsRestrictedFalse( var_handle ) ) {
SetVariableByHandle( PreviousInstall, "1" );
SetVariableByHandle( var_handle, "1" );
}
}
break;
default:
break;
}
}
#ifdef PATCH
static void EndHandle( char *source )
/***********************************/
// ASSUMES the source has room for additional '\'
{
int length;
length = strlen( source );
#if defined( __UNIX__ )
if( source[ length - 1 ] != '/' ) {
source[ length ] = '/';
source[ length + 1 ] = '\0';
}
#else
if( source[ length - 1 ] != '\\' ) {
source[ length ] = '\\';
source[ length + 1 ] = '\0';
}
#endif
}
static void GetDestDir( int i, char *buffer )
/********************************************/
{
char *temp;
char temp2[ _MAX_PATH ];
char drive[ _MAX_DRIVE ];
int intvalue = 0;
ReplaceVars( buffer, GetVariableStrVal( "DstDir" ) );
EndHandle( buffer );
intvalue = atoi( PatchInfo[ i ].destdir );
if( intvalue != 0 ) {
temp = strchr( DirInfo[ intvalue - 1 ].desc, '=' ) + 1;
}
else {
// if destination dir specifies the drive, just use it
ReplaceVars( temp2, PatchInfo[ i ].destdir );
_splitpath( temp2, drive, NULL, NULL, NULL );
if( drive[ 0 ] != 0 ) { // drive specified
strcpy( buffer, temp2 );
EndHandle( buffer );
return;
}
else {
temp = temp2;
}
}
strcat( buffer, temp );
EndHandle( buffer );
}
static int SecondaryPatchSearch( char *filename, char *buff, int Index )
/**********************************************************************/
{
// search for patch output files (originals to be patched) in following order
// 1.) check .INF specified directory in PatchInfo structure (if it exists)
// 2.) check DstDir "variable"
// 2b) if not found in %DstDir%\destdir just try %DstDir%
// 3.) check system path
// this function performs the first two checks, findold() in OLDFILE.C does
// system path search, if first two searches fail and this function returns
// nonzero.
char path[ _MAX_PATH ];
char ext[ _MAX_EXT ];
buff[ 0 ] = '\0';
GetDestDir( Index, path );
strcat( path, filename );
if( access( path, F_OK ) == 0 ) {
strcpy( buff, path );
return( TRUE );
} else {
ReplaceVars( path, GetVariableStrVal( "DstDir" ) );
EndHandle( path );
strcat( path, filename );
if( access( path, F_OK ) == 0 ) {
strcpy( buff, path );
return( TRUE );
}
}
_splitpath( filename, NULL, NULL, NULL, ext );
if( stricmp( ext, ".dll" ) == 0 ) {
_searchenv( filename, "PATH", buff );
}
return( buff[ 0 ] != '\0' );
}
extern void PatchingFile( char *patchname, char *path )
/*****************************************************/
{
char buff[200];
strcpy( buff, patchname );
strcat( buff, " to file " );
strcat( buff, path );
StatusLines( STAT_PATCHFILE, buff );
StatusShow( TRUE );
}
#endif
static char *NextToken( char *buf, char delim )
/*********************************************/
// Locate the next 'token', delimited by the given character. Return a
// pointer to the next one, and trim trailing blanks off the current one.
{
char *p, *q;
if( buf == NULL ) {
return( NULL );
}
p = strchr( buf, delim );
if( p != NULL ) {
*p = '\0';
q = p - 1;
while( q >= buf && ( *q == ' ' || *q == '\t' ) ) {
*q = '\0';
--q;
}
++p;
while( *p == ' ' || *p == '\t' ) ++p;
}
return( p );
}
static char *StripEndBlanks( char *p )
/************************************/
{
char *q;
if( p == NULL ) {
return p;
}
while( *p == ' ' || *p == '\t' )
++p;
q = p + strlen( p ) - 1;
while( q >= p && ( *q == ' ' || *q == '\t' || *q == '\n' ) ) {
*q = '\0';
--q;
}
return( p );
}
// Dialog parsing functions
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?