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 + -
显示快捷键?