langdat.c

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

C
708
字号
    char    *s_copy;
    char    *p;
    bool    result = FALSE;

    s_copy = strdup( str );
    p = FirstWord( s_copy );
    do {
        if( !strcmp( p, word ) ) {
            result = TRUE;
        }
        p = NextWord( p );
    } while( p != NULL );
    free( s_copy );
    return( result );
}

static void ProcessLine( const char *line )
{
    char    *cmd, *p, *str;
    char    *line_copy;
    char    *type, *redist, *dir, *usr, *rel, *cond;
    char    *pack, *where, *desc, *old, *patch, *dstvar;
    int     special = FALSE;

    type = DefType; redist = DefRedist; dir = DefDir; usr = DefUsr;
    rel = DefRel; cond = DefCond; pack = DefPack; where = DefWhere;
    desc = DefDesc; old = DefOld; patch = DefPatch; dstvar = DefDstvar;

    line_copy = strdup( line );
    p = SkipBlanks( line_copy );
    cmd = strtok( p, "=" );
    do {
        str = strtok( NULL, "\"" );
        if( !stricmp( cmd, "echo" ) ) {
            Log( TRUE, "%s\n", str );
            special = TRUE;
            break;
        } else if( !stricmp( cmd, "type" ) ) {
            type = str;
        } else if( !stricmp( cmd, "redist" ) ) {
            redist = str;
        } else if( !stricmp( cmd, "dir" ) ) {
            dir = str;
        } else if( !stricmp( cmd, "usr" ) ) {
            usr = str;
        } else if( !stricmp( cmd, "rel" ) ) {
            rel = str;
        } else if( !stricmp( cmd, "cond" ) ) {
            cond = str;
        } else if( !stricmp( cmd, "pack" ) ) {
            pack = str;
        } else if( !stricmp( cmd, "where" ) ) {
            where = str;
        } else if( !stricmp( cmd, "desc" ) ) {
            desc = str;
        } else if( !stricmp( cmd, "descr" ) ) {     //  Multiple spellings
            desc = str;
        } else if( !stricmp( cmd, "old" ) ) {
            old = str;
        } else if( !stricmp( cmd, "patch" ) ) {
            patch = str;
        } else if( !stricmp( cmd, "dstvar" ) ) {
            dstvar = str;
        } else {
            printf( "langdat warning: unknown keyword %s\n", cmd );
            printf( "(in file %s)\n", IncludeStk->name );
        }
        cmd = strtok( NULL, " \t=" );
    } while( cmd != NULL );
    if( !special ) {
        /* Check if 'where' matches specified product */
        if( !Product || !where || ContainsWord( where, Product ) ) {
            Log( TRUE, "<%s><%s><%s><%s><%s><%s><%s><%s><%s>\n",
                redist, dir, old, usr, rel, where, dstvar, cond, desc );
        }
    }
    free( line_copy );
}

static void ProcessDefault( const char *line )
{
    char    *cmd, *p, *q, *str;
    char    *line_copy;

    /* Reset any existing defaults */
    if( DefType != NULL ) free( DefType );
    if( DefRedist != NULL ) free( DefRedist );
    if( DefDir != NULL ) free( DefDir );
    if( DefUsr != NULL ) free( DefUsr );
    if( DefRel != NULL ) free( DefRel );
    if( DefCond != NULL ) free( DefCond );
    if( DefPack != NULL ) free( DefPack );
    if( DefWhere != NULL ) free( DefWhere );
    if( DefDesc != NULL ) free( DefDesc );
    if( DefOld != NULL ) free( DefOld );
    if( DefPatch != NULL ) free( DefPatch );
    if( DefDstvar != NULL ) free( DefDstvar );
    DefType = DefRedist = DefDir = DefUsr = DefRel = DefCond
    = DefPack = DefWhere = DefDesc = DefOld = DefPatch = DefDstvar = NULL;

    /* Process new defaults (if provided) */
    line_copy = strdup( line );
    p = SkipBlanks( line_copy );
    q = strtok( p, "]" );
    q += strlen( q ) - 1;
    while( (q >= p) && ((*q == ' ') || (*q == '\t')) ) --q;
    if( *q == '\"' ) ++q;
    *q = '\0';
    cmd = strtok( p, "=" );
    if( cmd != NULL ) {
        do {
            str = strtok( NULL, "\"" );
            if( !stricmp( cmd, "type" ) ) {
                DefType = strdup( str );
            } else if( !stricmp( cmd, "redist" ) ) {
                DefRedist = strdup( str );
            } else if( !stricmp( cmd, "dir" ) ) {
                DefDir = strdup( str );
            } else if( !stricmp( cmd, "usr" ) ) {
                DefUsr = strdup( str );
            } else if( !stricmp( cmd, "rel" ) ) {
                DefRel = strdup( str );
            } else if( !stricmp( cmd, "cond" ) ) {
                DefCond = strdup( str );
            } else if( !stricmp( cmd, "pack" ) ) {
                DefPack = strdup( str );
            } else if( !stricmp( cmd, "where" ) ) {
                DefWhere = strdup( str );
            } else if( !stricmp( cmd, "desc" ) ) {
                DefDesc = strdup( str );
            } else if( !stricmp( cmd, "old" ) ) {
                DefOld = strdup( str );
            } else if( !stricmp( cmd, "patch" ) ) {
                DefPatch = strdup( str );
            } else if( !stricmp( cmd, "dstvar" ) ) {
                DefDstvar = strdup( str );
            } else {
                printf( "langdat warning: unknown default %s\n", cmd );
                printf( "(in file %s)\n", IncludeStk->name );
            }
            cmd = strtok( NULL, " \t=" );
        } while( cmd != NULL );
    }
    free( line_copy );
}

/****************************************************************************
*
* MatchFound. Examines a string of space separated words. If the first word or
* words (between parentheses) matches any of the words following it, returns 1.
* If not, returns 0. String is terminated by 0 or ']'.
* If there isn't at least one word in the string, terminates program.
*
***************************************************************************/
static int MatchFound( char *p )
{
    char   *Match[20];                     // 20 is enough for builder
    int     MatchWords = 0;
    int     i;
    int     EmptyOk = FALSE;
    int     WordsExamined = 0;

    p = NextWord( p );
    if( p == NULL )
        Fatal( "Missing match word\n" );

    if( *p == '(' ) { // Multiple match words, store them
        p = NextWord( p );
        for( ; MatchWords < 20; ) {
            if( p == NULL )
                Fatal( "Missing match word\n" );
            if( stricmp( p, "\"\"" ) == 0 ) // 'No parameter' indicator
                EmptyOk = TRUE;
            else
                Match[MatchWords++] = p;
            p = NextWord( p );
            if( strcmp( p, ")" ) == 0 ) {
                p = NextWord( p );
                break;
            }
        }
    } else {
        Match[MatchWords++] = p;
        p = NextWord( p );
    }

    // At this point, p must point to the first word after the (last) match word

    for( ;; ) {
        if( p == NULL || strcmp( p, "]" ) == 0 ) { // End of string
            if( WordsExamined == 0 && EmptyOk )
                return 1;
            else
                return 0;
        }
        WordsExamined++;
        for( i = 0; i < MatchWords; i++ )
            if( stricmp( Match[i], p ) == 0 )
                return 1;
        p = NextWord( p );
    }
}

static void ProcessCtlFile( const char *name )
{
    char        *p;
    char        *log_name;
    bool        logit;

    PushInclude( name );
    while( GetALine( Line ) ) {
        SubstLine( Line, ProcLine );
        p = ProcLine;
        switch( *p ) {
        case '#':
        case '\0':
            /* just a comment */
            break;
        case '[':
            /* a directive */
            p = FirstWord( p + 1 );
            if( stricmp( p, "INCLUDE" ) == 0 ) {
                if( IncludeStk->skipping == 0 ) {
                    PushInclude( NextWord( p ) );
                }
            }
            else if( stricmp( p, "LOG" ) == 0 ) {
                if( IncludeStk->skipping == 0 ) {
                    log_name = NextWord( p );
                    p = NextWord( log_name );
                    if( LogFile == NULL ) {
                        OpenLog( log_name );
                    }
                }
            } else if( stricmp( p, "BLOCK" ) == 0 ) {
                IncludeStk->skipping = 0;   // New block: reset skip flags
                IncludeStk->ifdefskipping = 0;
                if( !MatchFound( p ) )
                    IncludeStk->skipping++;
                break;
            } else if( stricmp( p, "IFDEF" ) == 0 ) {
                if( IncludeStk->ifdefskipping != 0 )
                    IncludeStk->ifdefskipping--;
                if( !MatchFound( p ) )
                    IncludeStk->ifdefskipping++;
                break;
            } else if( stricmp( p, "ENDIF" ) == 0 ) {
                if( IncludeStk->ifdefskipping != 0 )
                    IncludeStk->ifdefskipping--;
                break;
            } else if( stricmp( p, "DEFAULT" ) == 0 ) {
                ProcessDefault( p + strlen( p ) + 1 );
            } else {
                Fatal( "Unknown directive '%s'\n", p );
            }
            break;
        default:
            /* a command */
            logit = ( VerbLevel > 0 );
            if( *p == '@' ) {
                logit = FALSE;
                p = SkipBlanks( p + 1 );
            }
            if( IncludeStk->skipping == 0 && IncludeStk->ifdefskipping == 0 ) {
                if( logit ) {
                    Log( FALSE, "+++<%s>+++\n", p );
                }
                strcpy( Line, p );
                ProcessLine( p );
                LogFlush();
            } else if( logit && ( VerbLevel > 1 ) ) {
                Log( FALSE, "---<%s>---\n", p );
            }
        }
    }
}

static bool SearchUpDirs( const char *name, char *result )
{
    char        buff[_MAX_PATH2];
    char        *drive;
    char        *dir;
    char        *fn;
    char        *ext;
    char        *end;
    FILE        *fp;

    _fullpath( result, name, _MAX_PATH );
    for( ;; ) {
        fp = fopen( result, "r" );
        if( fp != NULL ) {
            fclose( fp );
            return( TRUE );
        }
        _splitpath2( result, buff, &drive, &dir, &fn, &ext );
        end = &dir[strlen( dir ) - 1];
        if( end == dir )
            return( FALSE );
        switch( *end ) {
        case '\\':
        case '/':
            --end;
        }
        for( ;; ) {
            if( end == dir ) {
                *end++ = '/';
                break;
            }
            if( *end == '\\' || *end == '/' )
                break;
            --end;
        }
        *end = '\0';
        _makepath( result, drive, dir, fn, ext );
    }
}


int main( int argc, char *argv[] )
{
    ctl_file    *next;
    char        *p;

    SysInit( argc, argv );
    ProcessOptions( argv + 1 );
    if( Product == NULL ) {
        printf( "langdat warning: no product specified, processing all entries\n" );
    }
    if( CtlList == NULL ) {
        p = getenv( DEFCTLENV );
        if( p == NULL )
            p = DEFCTLNAME;
        if( !SearchUpDirs( p, Line ) ) {
#ifdef __WATCOMC__
            _searchenv( p, "PATH", Line );
#else
            Line[0] = '\0';
#endif
            if( Line[0] == '\0' ) {
                Fatal( "Can not find '%s'\n", p );
            }
        }
        AddCtlFile( Line );
    }
    while( CtlList != NULL ) {
        ProcessCtlFile( CtlList->name );
        next = CtlList->next;
        free( CtlList );
        CtlList = next;
    }
    CloseLog();
    return( 0 );
}

⌨️ 快捷键说明

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