source.c

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

C
685
字号
/****************************************************************************
*
*                            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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vi.h"
#include "posix.h"
#include "source.h"
#include "parsecl.h"
#include "menu.h"
#include "ex.h"
#include "fts.h"

static void finiSource( labels *, vlist *, sfile *, undo_stack * );
static int initSource( vlist *, char *);
static int barfScript( char *, sfile *, vlist *,int *, char *);
static void addResidentScript( char *, sfile *, labels * );
static resident *residentScript( char * );
static void finiSourceErrFile( char * );

/*
 * Source - main driver
 */
int Source( char *fn, char *data, int *ln )
{
    undo_stack  *atomic = NULL;
    labels      *lab,lb;
    vlist       vl;
    files       fi;
    sfile       *sf,*curr;
    char        tmp[MAX_SRC_LINE];
    char        sname[FILENAME_MAX];
    int         i,rc;
    bool        sicmp,wfb,ssa,exm;
    resident    *res;
    int         cTokenID;

    /*
     * startup
     */
    LastRC = LastRetCode;
    memset( &fi, 0, sizeof( fi ) );
    vl.head = vl.tail = NULL;
    res = residentScript( fn );
    if( res != NULL && EditFlags.LoadResidentScript ) {
        return( ERR_SCRIPT_ALREADY_RESIDENT );
    }
    if( EditFlags.CompileScript || res == NULL ) {
        lab = &lb;
        memset( lab, 0, sizeof( labels ) );
        sf = NULL;
    } else {
        lab = &res->lab;
        sf = res->sf;
    }
    if( EditFlags.CompileScript ) {
        sname[0] = 0;
        NextWord1( data, sname );
    }

    /*
     * initialize variables
     */
    memset( &fi, 0, sizeof( fi ) );
    i = initSource( &vl, data );
    if( i ) {
        return( i );
    }

    /*
     * pre-process
     */
    sicmp = EditFlags.ScriptIsCompiled;
    SourceErrCount = 0;
    if( EditFlags.CompileScript || res == NULL ) {
        EditFlags.ScriptIsCompiled = FALSE;
        i = PreProcess( fn, &sf, lab );
        finiSourceErrFile( fn );
        if( i ||  SourceErrCount > 0 ) {
            EditFlags.ScriptIsCompiled = sicmp;
            return( i );
        }
    } else {
        EditFlags.ScriptIsCompiled = res->scriptcomp;
    }

    /*
     * if we were loading a resident script, then add it
     */
    if( EditFlags.LoadResidentScript ) {
        finiSource( NULL, &vl, NULL, NULL );
        if( SourceErrCount == 0 ) {
            addResidentScript( fn, sf, lab );
        }
        EditFlags.ScriptIsCompiled = sicmp;
        return( ERR_NO_ERR );
    }

    /*
     * if we were compiling, dump results and go back
     */
    if( EditFlags.CompileScript ) {
        rc = barfScript( fn, sf, &vl,ln, sname );
        finiSource( lab, &vl, sf, NULL );
        return( rc );
    }

    /*
     * process each source line
     */
    exm = EditFlags.ExMode;
    wfb = EditFlags.WatchForBreak;
    ssa = EditFlags.SourceScriptActive;
    EditFlags.SourceScriptActive = TRUE;
    EditFlags.WatchForBreak = TRUE;
    EditFlags.ExMode = TRUE;
    curr = sf->next;
    while( curr != NULL ) {

        cTokenID = curr->token - SRC_T_NULL - 1;

        if( !EditFlags.Starting ) {
            if( EditFlags.BreakPressed ) {
                ClearBreak();
                break;
            }
        }
        rc = LastError = ERR_NO_ERR;
        if( curr->data != NULL ) {
            strcpy( tmp, curr->data );
        } else {
            tmp[0] = 0;
        }

        if( EditFlags.Appending ) {
            if( curr->hasvar) {
                Expand( tmp, &vl );
            }
            rc = AppendAnother( tmp );
            goto evil_continue;
        }

        if( cTokenID == PCL_T_ENDFILETYPESOURCE ) {
            rc = FTSEnd();
            goto evil_continue;
        }

        if( EditFlags.FileTypeSource ) {
            rc = FTSAddCmd( tmp, curr->token );
            goto evil_continue;
        }

        if( curr->token > SRC_T_NULL ) {

            if( curr->hasvar) {
                Expand( tmp, &vl );
            }
            rc = TryCompileableToken( cTokenID, tmp, FALSE, 0 );
            if( rc == NOT_COMPILEABLE_TOKEN ) {
                rc = ProcessWindow( cTokenID, tmp );
            }
            if( rc < 0 ) {
                rc = ERR_NO_ERR;
            }

        } else switch( curr->token ) {
        case SRC_T_ATOMIC:
            if( atomic == NULL ) {
                atomic = UndoStack;
                StartUndoGroup( atomic );
            }
            break;

        case SRC_T_IF:
            rc = SrcIf( &curr, &vl );
            break;

        case SRC_T_GOTO:
            rc = SrcGoTo( &curr, tmp, lab );
            break;

        case SRC_T_LABEL:
            break;

        case SRC_T_RETURN:
            if( curr->data != NULL ) {
                GetErrorTokenValue( &rc, curr->data );
            } else {
                rc = ERR_NO_ERR;
            }
            goto evil_exit;

        case SRC_T_GET:
            SrcGet( tmp, &vl );
            rc = ERR_NO_ERR;
            break;

        case SRC_T_INPUT:
            LastRC = SrcInput( tmp, &vl );
            if( LastRC != NO_VALUE_ENTERED && LastRC != ERR_NO_ERR ) {
                rc = LastRC;
            }
            break;

        case SRC_T_NEXTWORD:
            rc = SrcNextWord( tmp, &vl );
            break;

        case SRC_T_ASSIGN:
            rc = SrcAssign( tmp, &vl );
            break;

        case SRC_T_EXPR:
            rc = SrcExpr( curr, &vl );
            break;

        case SRC_T_OPEN:
            LastRC = SrcOpen( curr, &vl, &fi, tmp );
            if( LastRC != ERR_FILE_NOT_FOUND && LastRC != ERR_NO_ERR ) {
                rc = LastRC;
            }
            break;

        case SRC_T_READ:
            LastRC = SrcRead( curr, &fi, tmp, &vl );
            if( LastRC != END_OF_FILE && LastRC != ERR_NO_ERR ) {
                rc = LastRC;
            }
            break;

        case SRC_T_WRITE:
            rc = SrcWrite( curr, &fi, tmp, &vl );
            break;

        case SRC_T_CLOSE:
            rc = SrcClose( curr, &vl, &fi, tmp );
            break;

        default:
            #ifdef __WIN__
                {
                    extern bool RunWindowsCommand( char *, long *, vlist * );
                    if( RunWindowsCommand( tmp, &LastRC, &vl ) ) {
                        rc = LastRC;
                        break;
                    }
                }
            #endif
            if( curr->hasvar ) {
                Expand( tmp, &vl );
            }
            LastRC = RunCommandLine( tmp );
            if( LastRC == DO_NOT_CLEAR_MESSAGE_WINDOW ) {
                LastRC = LastError;
            }
            break;
        }

evil_continue:
        if( rc ) {
            break;
        }
        curr = curr->next;

    }

evil_exit:
    if( EditFlags.Appending ) {
        AppendAnother( "." );
    }
    if( curr != NULL ) {
        *ln = curr->line;
    } else {
        *ln = CurrentSrcLine;
        rc = ERR_NO_ERR;
    }
    EditFlags.WatchForBreak = wfb;
    EditFlags.SourceScriptActive = ssa;
    EditFlags.ScriptIsCompiled = sicmp;
    EditFlags.ExMode = exm;
    if( res != NULL && !EditFlags.CompileScript ) {
        sf = NULL;
        lab = NULL;
    }
    finiSource( lab, &vl, sf, atomic );
    return( rc );

} /* Source */

/*
 * initSource - initialize language variables
 */
static int initSource( vlist *vl, char *data )
{
    int         i,j;
    char        tmp[MAX_SRC_LINE],name[MAX_NUM_STR],all[MAX_SRC_LINE];

    all[0] = 0;

    /*
     * break up command line parms
     */
    j = 1;
    while( TRUE ) {

        i = GetStringWithPossibleQuote( data, tmp );
        if( i ) {
            break;
        }
        VarAddStr( itoa( j, name, 10 ), tmp, vl );
        StrMerge( 2, all, tmp, SingleBlank );
        j++;

⌨️ 快捷键说明

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