grep.c

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

C
669
字号
     * got list of matches, so lets select an item, shall we?
     */
    CloseAWindow( wn );
    rc = ERR_NO_ERR;
    if( clist ) {

        /*
         * define display window dimensions
         */
        memcpy( &tw, &dirw_info, sizeof( window_info ) );
        tw.x1 = 14;
        tw.x2 = WindMaxWidth-2;
        i = tw.y2 - tw.y1+1;
        if( tw.has_border ) {
            i -= 2;
        }
        if( clist < i ) {
            tw.y2 -= ( i-clist );
        }
        if( clist > i ) {
            show_lineno = TRUE;
        } else {
            show_lineno = FALSE;
        }

        /*
         * build options window
         */
        memcpy( &wi, &extraw_info, sizeof( window_info ) );
        wi.x1 =0;
        wi.x2 = 13;
        i = DisplayExtraInfo( &wi, &optwin, EditOpts, NumEditOpts );
        if( i ) {
            return( i );
        }

        /*
         * process selections
         */
        while( TRUE ) {

            if( n+1 > clist ) {
                n = clist-1;
            }
            memset( &si, 0, sizeof( si ) );
            si.wi = &tw;
            si.title = "Files With Matches";
            si.list = list;
            si.maxlist = clist;
            si.num = n;
            si.retevents = evlist;
            si.event = -1;
            si.show_lineno = show_lineno;
            si.cln = n+1;
            si.eiw = optwin;

            rc = SelectItem( &si );
            n = si.num;

            if( rc || n < 0 ) {
                break;
            }
            if( si.event == VI_KEY( F3 ) ) {
                s = 0;
                e = clist-1;
            } else {
                s = e = n;
            }
            for( cnt=s;cnt<=e;cnt++ ) {
                rc = getFile( list[ cnt ] );
                if( rc != ERR_NO_ERR ) break;
            }
            if( rc != ERR_NO_ERR || si.event == -1 ||
                        si.event == VI_KEY( F1 ) || si.event == VI_KEY( F3 ) ) {
                break;
            }
            MemFree( list[n] );
            for( i=n;i<clist-1;i++ ) {
                list[i] = list[i+1];
            }
            clist--;
            if( clist == 0 ) {
                break;
            }
            MoveWindowToFrontDammit( optwin, FALSE );

        }
        CloseAWindow( optwin );

    } else if( !rc ) {
        Message1( "String \"%s\" not found", sString );
        rc = DO_NOT_CLEAR_MESSAGE_WINDOW;
    }

    /*
     * cleanup
     */
    finiList( clist, list );
    return( rc );

} /* DoFGREP */
#endif

/*
 * fileGrep - search a single dir and build list of files
 */
static void fileGrep( char *dir, char **list, int *clist, window_id wn )
{
    char        fn[FILENAME_MAX],data[FILENAME_MAX],ts[FILENAME_MAX];
    char        path[FILENAME_MAX];
    char        drive[_MAX_DRIVE],directory[_MAX_DIR],name[_MAX_FNAME];
    char        ext[_MAX_EXT];
    int         i,j;

    /*
     * get file path prefix
     */
    _splitpath( dir, drive, directory, name, ext );
    strcpy( path, drive );
    strcat( path, directory );
//    _makepath( path, drive, directory, NULL,NULL );

    /*
     * run through each entry and search it; building a list of matches
     */
    i = GetSortDir( dir, FALSE );
    if( i ) {
        return;
    }
    for( i=0;i<DirFileCount;i++ ) {
        if( !(DirFiles[i]->attr & _A_SUBDIR ) ) {

            strcpy( fn,path );
            strcat( fn, DirFiles[i]->name );
            #ifdef __WIN__
                EditFlags.BreakPressed = SetGrepDialogFile( fn );
            #else
                DisplayLineInWindow( wn, 1,fn );
            #endif
            if( EditFlags.BreakPressed ) {
                return;
            }
            if( isFgrep ) {
                j = fSearch( fn, ts );
            } else {
                j = eSearch( fn, ts );
            }
            if( j==FGREP_FOUND_STRING ) {

                ExpandTabsInABuffer(ts,strlen(ts),data,MAX_DISP );
                strcpy( ts,data );
                MySprintf(data,"%X \"%s\"",fn,ts );
                #ifdef __WIN__
                    /*
                     * for windows - the handle passed in is the list box
                     * and the entire string is added to it but only the file
                     * name is added to the list
                     */
                    SendMessage( wn, LB_ADDSTRING, 0, (LONG)(LPVOID)data );
                    MySprintf( data, "%X", fn );
                #endif
                AddString( &(list[*clist]), data );
                (*clist)++;

            } else if( j ) {
                return;
            }
        }
    }

} /* fileGrep */

/*
 * eSearch - scan a file for a search string (extended)
 */
static int eSearch( char *fn, char *res )
{
    int         i;
    char        *buff;
    FILE        *f;

    /*
     * init for file i/o
     */
    f = fopen( fn,"r" );
    if( f == NULL ) {
        return( ERR_FILE_NOT_FOUND );
    }

    /*
     * read lines from the file, and search through them
     */
    buff = StaticAlloc();
    while( TRUE ) {

        if( fgets( buff,MaxLine-1,f ) == NULL ) {
            fclose( f );
            StaticFree( buff );
            return( ERR_NO_ERR );
        }
        buff[ strlen(buff)-1 ] = 0;
        i = RegExec( cRx, buff, TRUE );
        if( RegExpError != ERR_NO_ERR ) {
            StaticFree( buff );
            return( RegExpError );
        }
        if( i ) {
            for( i=0;i<MAX_DISP;i++ ) {
                res[i] = buff[i];
            }
            res[i] = 0;
            fclose( f );
            StaticFree( buff );
            return( FGREP_FOUND_STRING );
        }

    }

} /* eSearch */

/*
 * fSearch - scan a file for a search string (fast)
 */
static int fSearch( char *fn, char *r )
{
    int         i,handle,j;
    int         bytes,bcnt;
    char        *buffloc,*strloc,*buff,*res;
    int         bytecnt;
    char        context_display[MAX_DISP];

    /*
     * init for file i/o
     */
    i = FileOpen( fn, FALSE, O_BINARY | O_RDONLY, 0, &handle );
    if( i ) {
        return( i );
    }
    #if !defined( __NT__ ) && defined( __WATCOMC__ )
        bytecnt = 3*stackavail()/4;
    #else
        bytecnt = 2048;
    #endif
    buff = alloca( bytecnt+2 );
    if( buff == NULL ) {
        return( ERR_NO_STACK );
    }

    /*
     * read in buffers from the file, and search through them
     */
    strloc = sString; // don't reset at start of new block - could span blocks
    while( 1 ) {

        bcnt = bytes = read( handle, buff, bytecnt );
        buffloc = buff;
        while( bytes ) {

            if( *strloc == cTable[*buffloc] ) {
                buffloc++;
                bytes--;
                strloc++;
                if( ! (*strloc) ) {
                    close( handle );
                    j = 0;
                    if( buffloc - strlen( sString ) < buff ) {
                        // match spans blocks - see context_display
                        res = context_display+MAX_DISP-1;
                        while( 1 ) {
                            if( *res == LF || res == context_display ) {
                                if( *res == LF ) {
                                    res++;
                                }
                                break;
                            }
                            res--;
                        }
                        // copy the part of the string NOT in buff
                        while( 1 ) {
                           if( j == MAX_DISP || *res == CR || *res == LF || res == &context_display[MAX_DISP] ) {
                                r[j] = 0;
                                break;
                            }
                            r[j++] = *res;
                            res++;
                        }
                        res = buff;
                    } else {
                        res = &buffloc[ -strlen( sString ) ];
                        while( 1 ) {
                            if( *res == LF || res == buff ) {
                                if( *res == LF ) {
                                    res++;
                                }
                                break;
                            }
                            res--;
                        }
                    }
                    // now copy the string ( all that is in buff )
                    while( 1 ) {
                       if( j == MAX_DISP || *res == CR || *res == LF || res == &buff[bytecnt] ) {
                            r[j] = 0;
                            break;
                        }
                        r[j++] = *res;
                        res++;
                    }
                    return( FGREP_FOUND_STRING );
                }
            } else {
                if( strloc == sString ) {
                    buffloc++;
                    bytes--;
                } else {
                    strloc = sString;
                }
            }

        }
        if( bcnt != bytecnt ) {
            break;
        }
        if( strloc != sString ) {
            // partial match -- keep the last bunch of text as context
            strncpy( context_display, buffloc-MAX_DISP, MAX_DISP );
        }

    }
    close( handle );
    return( ERR_NO_ERR );

} /* fSearch */

⌨️ 快捷键说明

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