browse.c

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

C
833
字号
/****************************************************************************
*
*                            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 <sys/types.h>
#include <sys/stat.h>
#include <malloc.h>
#include <string.h>
#ifdef __QNX__
#include <dirent.h>
#else
#include "direct.h"
#endif
#include "stdui.h"
#include "dirui.h"
#include "uivedit.h"

#ifndef NULL
#define NULL            0               /* NULL pointer         */
#endif
#define TRUE            (0==0)          /* TRUE                 */
#define FALSE           (0==1)          /* FALSE                */
#define bool            int             /* boolean value        */

/* N.B. DIR_MAX must be the same as UTIL_LEN in dbgdefn.h */
#define DIR_MAX         80              /* max length of path   */

/* N.B. if the value of ERROR is changed here it must also be changed
 * in dbgmenu1.c */
#define EV_ERROR        -1              /* error return value   */

#define OK_DIR           1              /* return codes for DisplayDir */
#define NO_MEM_4_DIR    -1
#define INVALID_DIR     -2

#ifdef __QNX__
#   define  IS_DIR( dir )   S_ISDIR((dir)->d_stat.st_mode)
#   define  FULL_MASK       "*"
#   define  PATH_SEP        '/'
#else
#   define  IS_DIR( dir )   (((dir)->d_attr & _A_SUBDIR)!=0)
#   define  FULL_MASK       "*.*"
#   define  PATH_SEP        '\\'
#endif

struct name {
        bool dir;
        char str[ NAME_MAX + 7 ];
};

static struct name *Names = NULL;

static EVENT DirEvents[] = {
        EV_NO_EVENT,            /* end of list of ranges */
        EV_MOUSE_PRESS,
        EV_MOUSE_DRAG,
        EV_MOUSE_DCLICK,
        EV_MOUSE_RELEASE,
        EV_CURSOR_UP,
        EV_CURSOR_DOWN,
        EV_RETURN,
        EV_ESCAPE,
        EV_NO_EVENT
};

static EVENT GetDirEvents[] = {
        EV_NO_EVENT,            /* end of list of ranges */
        EV_MOUSE_PRESS,
        EV_MOUSE_DCLICK,
        EV_CURSOR_UP,
        EV_CURSOR_DOWN,
        EV_RETURN,
        EV_ESCAPE,
        EV_NO_EVENT
};

static VEDITLINE DirEdit = {
        0, 0,                   /* first line of window */
        NAME_MAX + 7,           /* length of field      */
        0,                      /* first visible char   */
        0,                      /* buffer length        */
        NULL,                   /* character buffer     */
        0,                      /* cursor in buffer     */
        0,                      /* attribute            */
        FALSE,                  /* buffer changed       */
        TRUE,                   /* update               */
        FALSE,                  /* autoclear line       */
        FALSE                   /* invisible line       */
};

static  char            FullMask[] = FULL_MASK;


 static void outnames( wptr, dirptr, start, stop )
/*************************************************/

    register VSCREEN            *wptr;
    register DIRECTORY          *dirptr;
    register int                start;
    register int                stop;
{
    register int                index;
    register ORD                row;
    register int                attr;
    register char               *str;

    for( index = start; index <= stop; ++index ) {
        row = index - dirptr->index + dirptr->currrow;
        if( ( row > 0 ) && ( row < wptr->area.height ) ) {
            if( index == dirptr->index ) {
                attr = ATTR_EDIT;
            } else {
                attr = ATTR_NORMAL;
            }
            if( index < dirptr->dirsize ) {
                str = Names[ index ].str;
            } else {
                str = "";
            }
            uivtextput( wptr, row, 0, UIData->attrs[ attr ], str,
                        wptr->area.width );
        }
    }
}

#ifdef __QNX__
static void add_name( DIRECTORY *direct, char *name, char **where )
{
    char    *add_point;

    add_point = &direct->pathbuff[ strlen( direct->pathbuff ) ];
    if( where != NULL ) *where = add_point;
    if( add_point > direct->pathbuff && add_point[-1] != '/' ) {
        *add_point++ = '/';
    }
    strcpy( add_point, name );
}
#endif

static struct dirent *my_readdir( DIRECTORY *direct, DIR *dp )
{
    struct dirent   *dir;

    direct = direct;
    dir = readdir( dp );
    if( dir == NULL ) return( NULL );
#ifdef __QNX__
    if( !(dir->d_stat.st_status & _FILE_USED) ) {
        char            *where;

        add_name( direct, dir->d_name, &where );
        stat( direct->pathbuff, &dir->d_stat );
        *where = '\0';
    }
#endif
    return( dir );
}


#ifdef __QNX__
/*  checks name for match with wildcard mask */
/*  currently only supports masks of type *.ext */
static bool checkMask( char *name, char *mask )
{
    if( mask == NULL) return( TRUE );
    if( mask[0] == '*' && mask[1] == '.' &&
                ( strcspn( &mask[2], "*?" ) == strlen( &mask[2] ) ) ) {
        mask++;
        if( stricmp( mask, name+strlen(name)-strlen(mask) ) == 0 ) {
            return( TRUE );     /* wildcard matches */
        } else {
            return( FALSE );    /* wildcard doesn't match */
        }
    } else {
        return( TRUE );         /* mask type is unsupported */
    }
}
#endif


 static int addnames( dirptr, mask, flag, index )
/************************************************/

    register DIRECTORY          *dirptr;
    register char               *mask;
    register int                flag;
    register int                index;
{
    register int                len;
#ifndef __QNX__
    register char               *str;
#endif
    register DIR                *dptr;
    register int                add_mask;
    struct   dirent             *direntp;

    add_mask = concat( dirptr, mask );
    dptr = opendir( dirptr->pathbuff );
    if( dptr != NULL ) {
        for( ;; ) {
#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 ) {
                Names[ index ].dir = flag;
                len = 0;
#ifdef __QNX__
#define NAME_START 6
                strcpy( &Names[ index ].str[0], flag ? "<DIR> " : "      " );
                strcpy( &Names[ index ].str[NAME_START], direntp->d_name );
#else
#define NAME_START 0
                str = direntp->d_name;
                while( *str != '\0' ) {
                    if( ( *str == '.' ) && ( *( str-len ) != '.' ) ) {
                        ++str;
                        break;
                    }
                    Names[ index ].str[ len ] = *str;
                    ++str;
                    ++len;
                }
                while( len < 9 ) {
                    Names[ index ].str[ len ] = ' ';
                    ++len;
                }
                strcpy( Names[ index ].str + len, str );
                len = strlen( Names[ index ].str );
                while( len < 14 ) {
                    Names[ index ].str[ len ] = ' ';
                    ++len;
                }
                Names[ index ].str[ len ] = '\0';
                if( Names[ index ].dir ) {
                    memcpy( Names[ index ].str + 13, "<DIR>", 6 );
                }
#endif
                ++index;
            }
        }
        closedir( dptr );
    }
    if( add_mask ) {
        strip( dirptr, NULL );
    }
    return( index );
}


 static makedir( char *buff )
/***************************/
{
#ifdef __QNX__
    buff = buff;
#else
    register int                len;

    len = strlen( buff );
    buff += len - 1;
    if( buff[ 0 ] != PATH_SEP ) {
        buff[ 1 ] = PATH_SEP;
        buff[ 2 ] = '\0';
    }
#endif
}


 static int outdir( VSCREEN *wptr, char *buff )
/*********************************************/
{
    register int                len;
    register int                width;

    len = strlen( buff );
    width = wptr->area.width;
    if( len >= width ) {
        len -= width - 1;
    } else {
        len = 0;
    }
    buff += len;
    uivtextput( wptr, 0, 0, UIData->attrs[ ATTR_BRIGHT ], buff, width );
    return( len );
}


 static int concat( DIRECTORY *dirptr, char *str )
/************************************************/
{
#ifdef __QNX__
    dirptr = dirptr;
    str = str;
#else
    register char               *buf;

    buf = dirptr->pathbuff;
    while( ( *buf != ' ' ) && ( *buf != '\0' ) ) {
        ++buf;
    }
    if( ( buf == dirptr->pathbuff ) ||
        ( *( buf - 1 ) == PATH_SEP ) ||
        ( *( buf - 1 ) == ':' ) ) {
        if( *str != '.' ) {
            for( ;; ) {
                if( *str == ' ' ) {
                    while( *str == ' ' ) {
                        ++str;
                    }
                    if( ( *str != '<' ) && ( *str != '\0' ) ){
                        *buf++ = '.';
                    } else {
                        break;
                    }
                }
                *buf = *str;
                if( *buf == '\0' ) {
                    break;
                }
                ++buf;
                ++str;
            }
        }
    } else {
        return( FALSE );
    }
    *buf = '\0';
#endif
    return( TRUE );
}


 static int strip( DIRECTORY *dirptr, char *mask )
/************************************************/
{
#ifdef __QNX__
    dirptr = dirptr;
    mask = mask;
#else
    register char               *buf;

    buf = dirptr->pathbuff + strlen( dirptr->pathbuff ) - 1;
    while( buf >= dirptr->pathbuff ) {
        --buf;
        if( ( buf < dirptr->pathbuff ) ||
            ( *buf == PATH_SEP ) ||
            ( *buf == ':' ) ) {
            if( mask != NULL ) {
                strcpy( mask, buf + 1 );
            }
            *( buf+1 ) = '\0';
            return( TRUE );
        }
    }
    makedir( buf );
#endif
    return( FALSE );
}


 static int dircount( dirptr, mask, flag )
/*****************************************/

    register DIRECTORY          *dirptr;
    register char               *mask;
    register int                flag;
{
    register unsigned           count;
    register DIR                *dptr;
    register int                add_mask;
    struct   dirent             *direntp;

    count = 0;
    if( mask != NULL ) {
        add_mask = concat( dirptr, mask );
    } else {
        add_mask = FALSE;
    }
    dptr = opendir( dirptr->pathbuff );
    if( dptr == NULL ) {
        count = INVALID_DIR;
    } else {
        for( ;; ) {

⌨️ 快捷键说明

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