source.c

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

C
685
字号
    }
    VarAddStr( "*", all, vl );

    return( ERR_NO_ERR );

} /* initSource */

/*
 * finiSource - release language variables
 */
static void finiSource( labels *lab, vlist *vl, sfile *sf, undo_stack *atomic )
{
    sfile       *curr,*tmp;
    info        *cinfo;

    if( lab != NULL ) {
        MemFreeList( lab->cnt, lab->name );
        MemFree( lab->pos );
    }

    VarListDelete( vl );

    curr = sf;
    while( curr != NULL ) {
        tmp = curr->next;
        MemFree( curr->data );
        MemFree( curr->arg1 );
        MemFree( curr->arg2 );
        MemFree( curr );
        curr = tmp;
    }

    /*
     * make sure this undo stack is still around
     */
    if( atomic != NULL ) {
        cinfo = InfoHead;
        while( cinfo != NULL ) {
            if( atomic == cinfo->UndoStack ) {
                break;
            }
            cinfo = cinfo->next;
        }
        if( cinfo != NULL ) {
            EndUndoGroup( atomic );
        }
    }

} /* finiSource */

/*
 * FileSPVAR - build file special variables
 */
void FileSPVAR( void )
{
    char        path[FILENAME_MAX];
    char        drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
    int         i;

    /*
     * build path
     */
    if( CurrentFile == NULL ) {
        VarAddGlobalStr( "F", "" );
        VarAddGlobalStr( "H", "" );
        drive[0] = dir[0] = fname[0] = ext[0] = 0;
    } else {
        VarAddGlobalStr( "F", CurrentFile->name );
        VarAddGlobalStr( "H", CurrentFile->home );
        ConditionalChangeDirectory( CurrentFile->home );
        _splitpath( CurrentFile->name, drive, dir, fname, ext );
    }
    VarAddGlobalStr( "P1", dir );
    VarAddGlobalStr( "D1", drive );
    strcpy( path, drive );
    strcat( path, dir );
    i = strlen( path ) -1 ;
    if( path[i] == FILE_SEP && i > 0 ) {
        path[i] = 0;
    }
    if( CurrentFile != NULL ) {
        PushDirectory( path );
        ChangeDirectory( path );
        GetCWD2( path, FILENAME_MAX );
        PopDirectory();
    } else {
        path[0] = 0;
    }
    if( path[ strlen(path)-1 ] == FILE_SEP ) {
        StrMerge( 2, path, fname, ext );
    } else {
        StrMerge( 3, path,FILE_SEP_STR, fname, ext );
    }
    _splitpath( path, drive, dir, fname, ext );
    VarAddGlobalStr( "D", drive );
    VarAddGlobalStr( "P", dir );
    VarAddGlobalStr( "N", fname );
    VarAddGlobalStr( "E", ext );

} /* FileSPVAR */

static char srcErrFileName[] = "__err__.vi_";
static FILE *srcErrFile;
/*
 * SourceError - dump a source error
 */
void SourceError( char *msg )
{
    if( EditFlags.CompileScript ) {
        if( srcErrFile == NULL ) {
            srcErrFile = fopen( srcErrFileName, "w" );
            if( srcErrFile == NULL ) {
                return;
            }
        }
        MyFprintf( srcErrFile, "Error on line %d: \"%s\"\n",
                    CurrentSrcLine, msg );
    }
    SourceErrCount++;

} /* SourceError */


/*
 * finiSourceErrFile - close up error file
 */
static void finiSourceErrFile( char *fn )
{
    char        drive[_MAX_DRIVE],directory[_MAX_DIR],name[_MAX_FNAME];
    char        path[FILENAME_MAX];
    char        tmp[MAX_SRC_LINE];

    if( !EditFlags.CompileScript ) {
        return;
    }
    _splitpath( fn, drive, directory, name, NULL );
    _makepath( path, drive, directory, name,".err" );
    remove( path );
    if( srcErrFile != NULL ) {
        GetDateTimeString( tmp );
        MyFprintf( srcErrFile, "\nCompile of %s finished on %s\n",
                        fn, tmp );
        MyFprintf( srcErrFile, "%d errors encountered\n", SourceErrCount );
        fclose( srcErrFile );
        srcErrFile = NULL;
        rename( srcErrFileName, path );
    }

} /* finiSourceErrFile */

/*
 * barfScript - write a compiled script
 */
static int barfScript( char *fn, sfile *sf, vlist *vl, int *ln, char *vn )
{
    sfile       *curr;
    FILE        *foo;
    char        drive[_MAX_DRIVE],directory[_MAX_DIR],name[_MAX_FNAME];
    char        path[FILENAME_MAX];
    char        tmp[MAX_SRC_LINE],*tmp2;
    int         i,k,rc;

    /*
     * get compiled file name, and make error file
     */
    if( vn[0] == 0 ) {
        _splitpath( fn, drive, directory, name, NULL );
        _makepath( path,drive,directory,name,"._vi" );
    } else {
        strcpy( path, vn );
    }
    foo = fopen( path, "w" );
    if( foo == NULL ) {
        return( ERR_FILE_OPEN );
    }
    MyFprintf( foo,"VBJ__\n" );
    curr = sf;
    (*ln) = 1;

    /*
     * process all lines
     */
    while( TRUE ) {

        curr = curr->next;
        if( curr == NULL ) {
            break;
        }

        if( curr->data != NULL ) {
            strcpy( tmp, curr->data );
        } else {
            tmp[0] = 0;
        }

        /*
         * expand variables, if requested
         */
        if( EditFlags.CompileAssignments ) {
            /*
             * process the assign command
             */
            if( curr->token == SRC_T_ASSIGN ) {
                rc = SrcAssign( tmp, vl );
                if( rc ) {
                    fclose( foo );
                    return( rc );
                }
                if( !EditFlags.CompileAssignments ) {
                    strcpy( tmp, curr->data );
                    EditFlags.CompileAssignments = TRUE;
                } else {
                    continue;
                }
            } else {
                if( curr->token != SRC_T_IF ) {
                    if( curr->hasvar ) {
                        Expand( tmp, vl );
                        curr->hasvar = FALSE;
                        k = strlen( curr->data );
                        for( i=0;i<k;i++ ){
                            if( curr->data[i] == '%' ) {
                                curr->hasvar = TRUE;
                                break;
                            }
                        }
                    }
                }
            }
        }

        /*
         * process any additional commands
         */
        switch( curr->token ) {
        /*
         * process the map command
         */
        case PCL_T_MAP+ SRC_T_NULL + 1:
            if( tmp[0] == '!' ) {
                k = MAPFLAG_DAMMIT;
                tmp2 = &tmp[1];
            } else {
                k = 0;
                tmp2 = tmp;
            }
            rc = MapKey( k, tmp2 );
            if( rc ) {
                fclose( foo );
                return( rc );
            }
            if( k ) {
                tmp[0] = '!';
            }
            strcpy( &tmp[k], WorkLine->data );
            break;
        }

        /*
         * spew out line
         */
        MyFprintf( foo,"%c%d %s", (char)((char)curr->hasvar+'0'),curr->token, tmp);
        if( curr->token == SRC_T_GOTO ) {
            MyFprintf( foo," %d", curr->branchcond );
        }
        MyFprintf( foo,"\n" );
        (*ln) += 1;

    }
    fclose( foo );
    return( ERR_NO_ERR );

} /* barfScript */


static resident *resHead=NULL;
/*
 * addResidentScript - add a script to the resident list
 */
static void addResidentScript( char *fn, sfile *sf, labels *lab )
{
    resident    *tmp;

    tmp = MemAlloc( sizeof( resident ) );
    AddString( &tmp->fn, fn );
    tmp->sf = sf;
    memcpy( &tmp->lab, lab, sizeof( labels ) );
    tmp->scriptcomp = EditFlags.ScriptIsCompiled;
    tmp->next = resHead;
    resHead = tmp;

} /* addResidentScript */


/*
 * DeleteResidentScripts - delete the resident list
 */
void DeleteResidentScripts( void )
{
    resident    *tmp,*tmp_next;
    sfile       *curr,*next;

    for( tmp = resHead; tmp != NULL; ){
        tmp_next = tmp->next;

        MemFreeList( tmp->lab.cnt, tmp->lab.name );
        MemFree( tmp->lab.pos );

        curr = tmp->sf;
        while( curr != NULL ) {
            next = curr->next;
            MemFree( curr->data );
            MemFree( curr->arg1 );
            MemFree( curr->arg2 );
            MemFree( curr );
            curr = next;
        }
        MemFree( tmp->fn );
        MemFree( tmp );

        tmp = tmp_next;
    }
} /* DeleteResidentScripts */


/*
 * residentScript - check for a resident script
 */
static resident *residentScript( char *fn )
{
    resident    *tmp=resHead;

    while( tmp != NULL ) {
        if( !stricmp( fn, tmp->fn ) ) {
            break;
        }
        tmp = tmp->next;
    }
    return( tmp );

} /* residentScript */

⌨️ 快捷键说明

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