mlexprs.c

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

C
686
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <stdlib.h>

#include "massert.h"
#include "mtypes.h"
#include "mlex.h"
#include "macros.h"
#include "make.h"
#include "mmemory.h"
#include "mmisc.h"
#include "mpreproc.h"
#include "mrcmsg.h"
#include "msg.h"
#include "mvecstr.h"


char    *targ_path;
char    *dep_path;


STATIC TOKEN_T lexLongFilePathName( STRM_T t, TOKEN_T tok )
/**********************************************************
 * This will enable taking in of special filenames
 * it takes long file names or long path names
 */
{
    char    file[_MAX_PATH];
    int     pos;

    assert( t == DOUBLEQUOTE );

    pos = 0;

    t = PreGetCH();

    /* \" is considered a double quote character                         */
    /* and if a double quote is found again then we break out as the end */
    /* of the filename                                                   */
    while( pos < _MAX_PATH && t != DOUBLEQUOTE && t != EOL && t != STRM_END ) {
        file[pos++] = t;
        t = PreGetCH();
        if( t == BACKSLASH ) {
            if( pos >= _MAX_PATH ) {
                break;
            }
            t = PreGetCH();
            if( t == DOUBLEQUOTE ) {
                file[pos++] = t;
                t = PreGetCH();
            } else {
                file[pos++] = BACKSLASH;
            }
        }
    }

    if( pos >= _MAX_PATH ) {
        PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED
    }
    file[pos] = NULLCHAR;

    if( t != DOUBLEQUOTE ) {
        UnGetCH( t );
    }

    CurAttr.ptr = StrDupSafe( file );
    return( tok );
}


#ifdef __WATCOMC__
#pragma on (check_stack);
#endif
extern TOKEN_T LexPath( STRM_T t )
/*********************************
 * returns: ({filec}*";")+          TOK_PATH
 *          EOL                     EOL
 *          STRM_END                STRM_END
 */
{
    char        path[_MAX_PATH];
    char        string_open;
    unsigned    pos;
    VECSTR      vec;                /* we'll store file/path here */

    for( ;; ) {                     /* get first valid character */
        if( t == EOL || t == STRM_END ) {
                /* now we pass this to LexParser() so that it can reset */
            return( LexParser( t ) );
        }

        if( t == STRM_MAGIC ) {
            InsString( DeMacro( EOL ), TRUE );
        } else if( !isfilec( t ) && t != PATH_SPLIT && t != ';' && t != '\"' &&
                !isws( t ) ) {
            PrtMsg( ERR | LOC | EXPECTING_M, M_PATH );
        } else if( !isws( t ) ) {
            break;
        }

        t = PreGetCH(); /* keep fetching characters */
    }
    /* just so you know what we've got now */
    assert( isfilec( t ) || t == PATH_SPLIT || t == ';' || t == '\"' );

    vec = StartVec();

    pos = 0;
    for( ;; ) {
        /*
         * Extract path from stream. If double quote is found, start string mode
         * and ignore all filename character specifiers and just copy all
         * characters. String mode ends with another double quote. Backslash can
         * be used to escape only double quotes, otherwise they are recognized
         * as path seperators.  If we are not in string mode character validity
         * is checked against isfilec().
         */

        string_open = 0;

        while( pos < _MAX_PATH && t != EOL && t != STRM_END ) {
            if( t == BACKSLASH ) {
                t = PreGetCH();

                if( t == DOUBLEQUOTE ) {
                    path[pos++] = DOUBLEQUOTE;
                } else {
                    path[pos++] = BACKSLASH;

                    // make sure we don't cross boundaries
                    if( pos < _MAX_PATH ) {
                        path[pos++] = t;
                    }
                }
            } else {
                if( t == DOUBLEQUOTE ) {
                    string_open = !string_open;
                } else {
                    if( string_open ) {
                        path[pos++] = t;
                    } else if( isfilec( t ) ) {
                        path[pos++] = t;
                    } else {
                        break; // not valid path character, break out.
                    }
                }
            }

            t = PreGetCH();
        }

        if( string_open ) {
            FreeSafe( FinishVec( vec ) );
            PrtMsg( FTL | LOC | ERROR_STRING_OPEN );
        }

        if( pos == _MAX_PATH ) {
            FreeSafe( FinishVec( vec ) );
            PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED
        }

        path[pos] = NULLCHAR;
        WriteVec( vec, path );

        if( t != PATH_SPLIT && t != ';' ) {
            break;
        }

        pos = 0;
        path[pos++] = PATH_SPLIT;
        t = PreGetCH();        /* use Pre here to allow path;&(nl)path */
    }
    UnGetCH( t );

    CurAttr.ptr = FinishVec( vec );

    return( TOK_PATH );
}
#ifdef __WATCOMC__
#pragma off(check_stack);
#endif


#ifdef __WATCOMC__
#pragma on (check_stack);
#endif
STATIC TOKEN_T lexFileName( STRM_T t )
/*************************************
 * Now we need two ways of taking file names if the filename needs special
 * characters then use "filename"  this will ignore all the different
 * characters except for the quote which can be specified as \t
 */
{
    char        file[_MAX_PATH];
    unsigned    pos;

    assert( isfilec( t ) || t == DOUBLEQUOTE ||
       (Glob.microsoft || Glob.posix) && t == SPECIAL_TMP_DOL_C );

    if( t == DOUBLEQUOTE ) {
        return( lexLongFilePathName( t, TOK_FILENAME ) );
    }

    pos = 0;
    while( pos < _MAX_PATH && (isfilec( t ) ||
            t == SPECIAL_TMP_DOL_C && (Glob.microsoft || Glob.posix) ) ) {
        file[pos++] = t;
        t = PreGetCH();
    }
    if( pos == _MAX_PATH ) {
        PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED
    }
    file[pos] = NULLCHAR;
    UnGetCH( t );

    /* if it is a file, we have to check last position for a ':', and
     * trim it off if it's there */
    if( pos > 1 && file[pos - 1] == COLON ) {
        file[pos - 1] = NULLCHAR; /* trim a trailing colon */
        UnGetCH( COLON );       /* push back the colon */
        --pos;
    }
    /*
     * try to do the trim twice because if file ends with a double colon
     * it means its a double colon explicit rule
     */
    if( pos > 1 && file[pos - 1] == COLON ) {
        file[pos - 1] = NULLCHAR;   /* trim a trailing colon */
        UnGetCH( COLON );           /* push back the colon */
    }

    CurAttr.ptr = StrDupSafe( file );
    return( TOK_FILENAME );
}
#ifdef __WATCOMC__
#pragma off(check_stack);
#endif


STATIC BOOLEAN checkDotName( const char *str )
/*********************************************
 * check if str is a special dotname. If it is, set CurAttr.num to the
 * appropriate value, and return TRUE.  If not a special dotname
 * return FALSE.
 */
{
    char        **key;
    char const  *ptr;

    assert( str[0] == DOT );

    ptr = str + 1;
    key = bsearch( &ptr, DotNames, DOT_MAX,
            sizeof( char * ), (int (*)( const void*, const void* ))KWCompare );

    if( key == NULL ) {         /* not a special dot-name */
        return( FALSE );
    }

    CurAttr.num = (const char **)key - DotNames;

    assert( DOT_MIN < CurAttr.num && CurAttr.num < DOT_MAX );

    return( TRUE );
}

STATIC char *getCurlPath( void )
/*******************************
 * get the path between  { and }
 */
{
    TOKEN_T t;
    char    path[_MAX_PATH + 1];
    int     pos;

    pos = 0;

    t = PreGetCH();

    if( t == L_CURL_PAREN ) {
        t = PreGetCH();
        while( t != R_CURL_PAREN && t != EOL && pos < _MAX_PATH ) {
            path[pos++] = t;
            t = PreGetCH();
        }
        path[pos] = NULLCHAR;
        if( t == EOL ) {
            UnGetCH( EOL );
            PrtMsg( ERR | LOC | NON_MATCHING_CURL_PAREN);
        } else if( pos == _MAX_PATH ) {
            PrtMsg( WRN | LOC | PATH_TOO_LONG );
        }
        return( StrDupSafe( path ) );

    } else {
        UnGetCH( t );
        return( NULL );
    }
}


#ifdef __WATCOMC__
#pragma on (check_stack);
#endif
STATIC TOKEN_T lexDotName( void )
/********************************
 * Given that the last character was a DOT, input the maximum string
 * possible, and check if it is a TOK_DOTNAME, TOK_SUF, or TOK_SUFSUF
 * Special cases to look for: "."{dirc}; ".."{dirc}; ".."{extc}+;
 * and "."{extc}+"."
 * recognizes:  "."{extc}*              TOK_SUF
 *              "."{extc}*{extc}*       TOK_SUFSUF
 *              "."{dot-name}           TOK_DOTNAME

⌨️ 快捷键说明

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