browse.c

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

C
833
字号
#ifdef __QNX__
/* scan for next directory matching mask */
            do {
                direntp = my_readdir( dirptr, dptr );
            } while( direntp != NULL && !IS_DIR( direntp )
                               && !checkMask( direntp->d_name, mask ) );
#else
            direntp = my_readdir( dirptr, dptr );
#endif
            if( direntp == NULL ) break;
            if( IS_DIR( direntp ) == flag ) ++count;
        }
        closedir( dptr );
    }
    if( add_mask ) {
        strip( dirptr, NULL );
    }
    return( count );
}

 static void InvalidDir( DIRECTORY *dirptr, VSCREEN *wptr )
/**********************************************************/
{
    unsigned    i;
    int         row;

    DirEdit.scroll = 0;
    uivtextput( wptr, 1, 0, UIData->attrs[ ATTR_NORMAL ],
        "Invalid directory", wptr->area.width );
    for( i = 1; i <= wptr->area.height-1; i ++ ) {
        row = i - dirptr->index + dirptr->currrow;
        if( ( row > 0 ) && ( row < wptr->area.height ) ) {
            uivtextput( wptr, row, 0, UIData->attrs[ ATTR_NORMAL ], "",
                        wptr->area.width );
        }
    }
}


 static int displaydir( wptr, dirptr )
/*************************************/

    register VSCREEN            *wptr;
    register DIRECTORY          *dirptr;
{
    register int                index;
    register char               *mask;
    auto     char               buff[ DIR_MAX + 1 ];
             void               *tmp;
             int                ret;
    struct   stat               blk;

    Names = NULL;
    index = 0;
    mask = dirptr->mask;
    ret = stat( dirptr->pathbuff, &blk );
    if( ( ret == 0 ) && ( S_ISDIR( blk.st_mode ) ) ){
        makedir( dirptr->pathbuff );
    }
    if( concat( dirptr, FullMask ) == FALSE ) {
        index = dircount( dirptr, NULL, TRUE );
        if( index != INVALID_DIR ) {
            strip( dirptr, buff );
            mask = buff;
        } else {
            strip( dirptr, buff );
            mask = buff;
        }
    } else {
        strip( dirptr, NULL );
    }
    index = dircount( dirptr, FullMask, TRUE );
    if( index == INVALID_DIR ) {
        InvalidDir( dirptr, wptr );
        return( INVALID_DIR );
    }
    ret = dircount( dirptr, mask, 0 );
    if( ret != INVALID_DIR ) {
        index += ret;
    }
    dirptr->index = 0;
    dirptr->currrow = 1;
    if( index == 0 ) {
        dirptr->dirsize = 1;
    } else {
        dirptr->dirsize = index;
    }
    tmp = (void *)malloc( dirptr->dirsize * sizeof( struct name ) );
    if( tmp != NULL ) {
        Names = tmp;
        if( index == 0 ) {
            strcpy( Names[ index ].str, "." );
        } else {
            index = addnames( dirptr, FullMask, TRUE, 0 );
            addnames( dirptr, mask, 0, index );
        }
        concat( dirptr, mask );
        outnames( wptr, dirptr, 0, wptr->area.height - 1 );
        DirEdit.scroll = outdir( wptr, dirptr->pathbuff );
        DirEdit.update = TRUE;
        DirEdit.index = strlen( dirptr->pathbuff );
        return( OK_DIR );
    } else {
        return( NO_MEM_4_DIR );
    }
}


 int initdir( wptr, dirptr )
/***************************/

    register VSCREEN            *wptr;
    register DIRECTORY          *dirptr;
{
    int                         ret;

    makedir( dirptr->pathbuff );
    ret = displaydir( wptr, dirptr );
    if( ret == NO_MEM_4_DIR ) {
        return( FALSE );
    } else {
        return( TRUE );
    }
}


 static int getdir( wptr, dirptr, new_dir )
/*********************************/

    register VSCREEN            *wptr;
    register DIRECTORY          *dirptr;
             bool               *new_dir;
{
    register char               *str;
    register int                len;
    register EVENT              ev;
    register EVENT              new;
    register ATTR               attr;
    auto     char               olddir[ DIR_MAX + 1 ];
             int                ret;

    strcpy( olddir, dirptr->pathbuff );
    DirEdit.attr = UIData->attrs[ ATTR_BRIGHT ];
    DirEdit.fldlen = wptr->area.width;
    DirEdit.length = dirptr->pathbufflen;
    DirEdit.buffer = dirptr->pathbuff;
    DirEdit.dirty = TRUE;
    uipushlist( GetDirEvents );
    dirptr->pathbuff[ DirEdit.length ] = '\0';
    attr = UIData->attrs[ ATTR_NORMAL ];
    new = EV_NO_EVENT;
    DirEdit.update = TRUE;
    *new_dir = FALSE;
    do {
        ev = uiveditline( wptr, &DirEdit );
        switch( ev ) {
        case EV_ESCAPE:
            new = ev;
            break;
        case EV_RETURN:
            finidir( wptr, dirptr );
            len = 0;
            while( dirptr->pathbuff[ len ] != ' '
                        && dirptr->pathbuff[ len ] != '\0' ) {
                ++len;
            }
            dirptr->pathbuff[ len ] = '\0';
            ret = displaydir( wptr, dirptr );
            switch( ret ) {
            case NO_MEM_4_DIR:
                new = EV_ERROR;
                break;
            case OK_DIR:
                strcpy( olddir, dirptr->pathbuff );
                str = Names[ 0 ].str;
                uivtextput( wptr, 1, 0, attr, str, wptr->area.width );
                *new_dir = TRUE;
                break;
            case INVALID_DIR:
                *new_dir = TRUE;
            }
            break;
        case EV_CURSOR_DOWN:
            strcpy( dirptr->pathbuff, olddir );
            outdir( wptr, dirptr->pathbuff );
            if( *new_dir ){
                finidir( wptr, dirptr );
                displaydir( wptr, dirptr );
            }
            new = ev;
            break;
        }
    } while( new == EV_NO_EVENT );
    uipoplist();
    wptr->cursor = C_OFF;
    return( new );
}

#define NO_ROW  ((ORD)-1)

 EVENT directory( wptr, dirptr )
/*******************************/

    register VSCREEN            *wptr;
    register DIRECTORY          *dirptr;
{
    register EVENT              ev;
    register EVENT              new;
    SAREA                       area;
    register int                index;
    ORD                         row, col;
    bool                        got_new_dir;

    uipushlist( DirEvents );
    ev = uivgetevent( wptr );
    uipoplist();
    area.row = 0;
    area.col = 0;
    area.height = 1;
    area.width = wptr->area.width;
    new = EV_NO_EVENT;
    index = dirptr->index;
    got_new_dir = FALSE;
    switch( ev ) {

    case EV_CURSOR_UP :
        if( index > 0 ) {
            dirptr->index -= 1;
            if( dirptr->currrow == 1 ) {
                area.row = 1;
            }
        } else {
            /* turn off highlighting while getting new directory */
            dirptr->index ++;
            dirptr->currrow ++;
            outnames( wptr, dirptr, index, index );
            dirptr->index --;
            dirptr->currrow --;
            new = getdir( wptr, dirptr, &got_new_dir );
            if( !got_new_dir ) {
                outnames( wptr, dirptr, index, index );
            }
        }
        break;

    case EV_CURSOR_DOWN :
        if( index < dirptr->dirsize - 1 ) {
            dirptr->index += 1;
            if( dirptr->currrow == wptr->area.height - 1 ) {
                area.row = 2;
            }
        }
        break;

    case EV_PAGE_UP:
        if( index - ( wptr->area.height - 1 ) >= 0 ) {
            dirptr->index -= wptr->area.height - 1;
        } else {
            dirptr->index = 0;
        }
        dirptr->currrow = 1;
        area.row = NO_ROW;
        break;

    case EV_PAGE_DOWN:
        if( index + wptr->area.height - 1 <= dirptr->dirsize - 1 ) {
            dirptr->index += wptr->area.height - 1;
        } else {
            dirptr->index = dirptr->dirsize - 1;
        }
        dirptr->currrow = wptr->area.height - 1;
        if( dirptr->currrow > dirptr->dirsize ) {
            dirptr->currrow = dirptr->dirsize;
        }
        area.row = NO_ROW;
        break;

    case EV_MOUSE_PRESS:
        if( wptr != uivmousepos( wptr, &row, &col ) ) {
            new = EV_ESCAPE;
            break;
        }
    case EV_MOUSE_DCLICK:
    case EV_MOUSE_DRAG:
        if( wptr == uivmousepos( wptr, &row, &col ) ){
            dirptr->index += row - dirptr->currrow;
        }
        if( dirptr->index >= dirptr->dirsize )
            dirptr->index = dirptr->dirsize - 1;
        else if( dirptr->index < 0 ) {
            dirptr->index = 0;
        }
        break;

    case EV_MOUSE_RELEASE:
        if( wptr != uivmousepos( wptr, &row, &col ) ){
            break;
        } else if( row == 0 ) {
            /* turn off highlighting while getting new directory */
            dirptr->index ++;
            dirptr->currrow ++;
            outnames( wptr, dirptr, index, index );
            dirptr->index --;
            dirptr->currrow --;
            new = getdir( wptr, dirptr, &got_new_dir );
            if( ! got_new_dir ) {
                dirptr->currrow = 1;
                outnames( wptr, dirptr, index, index );
            }
            break;
        }
        /* fall through */
        ev = EV_RETURN;
    case EV_RETURN :
        if( Names[ index ].dir ) {
            if( Names[ index ].str[NAME_START] == '.' ) {
                if( Names[ index ].str[NAME_START+1] == '.' ) {
#ifdef __QNX__
                    char    *start;
                    char    *end;
                    char    chr;

                    start = dirptr->pathbuff;
                    if( start[0] == '/' ) {
                        ++start;
                        if( start[0] == '/' ) {
                            ++start;
                            for( ;; ) {
                                chr = *start;
                                if( chr == '\0' ) break;
                                ++start;
                                if( chr == '/' ) break;
                            }
                        }
                    }
                    end = &start[ strlen( start ) ];
                    while( end > start && *end != '/' ) --end;
                    *end = '\0';
                    finidir( wptr, dirptr );
                    if( displaydir( wptr, dirptr ) == NO_MEM_4_DIR ) {
                        return( EV_ERROR );
                    }
                    index = dirptr->index;
#else
                    //NYI: what to do for QNX?
                    strip( dirptr, NULL );
                    if( strip( dirptr, NULL ) ) {
                        finidir( wptr, dirptr );  /* frees up Names */
                        if( displaydir( wptr, dirptr ) == NO_MEM_4_DIR ) {
                            return( EV_ERROR );
                        }
                        index = dirptr->index;
                    } else {
                        new = ev;
                    }
#endif
                 }
            } else {
#ifdef __QNX__
                add_name( dirptr, &Names[ dirptr->index ].str[NAME_START], NULL );
#else
                strip( dirptr, NULL );
                concat( dirptr, Names[ dirptr->index ].str );
#endif
                finidir( wptr, dirptr );  /* frees up Names */
                if( initdir( wptr, dirptr ) == FALSE ) {
                    return( EV_ERROR );
                }
                index = dirptr->index;
            }
        } else {
#ifdef __QNX__
            add_name( dirptr, &Names[ dirptr->index ].str[NAME_START], NULL );
#else
            strip( dirptr, NULL );
            concat( dirptr, Names[ dirptr->index ].str );
#endif
            finidir( wptr, dirptr );
            new = ev;
        }
        break;

    default :
        new = ev;
        break;
    }
    if( !got_new_dir ) {
        if( index != dirptr->index ) {
            if( area.row == NO_ROW ) {
                index = dirptr->index - dirptr->currrow;
                outnames( wptr, dirptr, index, index + wptr->area.height- 1 );
            } else if( area.row > 0 ) {
                area.height = wptr->area.height - 2;
                uivmoveblock( wptr, area, index - dirptr->index, 0 );
            } else {
                dirptr->currrow += dirptr->index - index;
            }
            outnames( wptr, dirptr, index, index );
            outnames( wptr, dirptr, dirptr->index, dirptr->index );
        }
    }
    return( new );
}


#pragma off(unreferenced);
 void finidir( VSCREEN *wptr, DIRECTORY *dirptr )
/***********************************************/
#pragma on(unreferenced);
{
    if( Names != NULL ) {
        free( Names );
        Names = NULL;
    }
}

⌨️ 快捷键说明

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