4
* All rights reserved. Copyright (C) 1996 by NARITA Tomio.
5
* $Id: find.c,v 1.5 2003/11/13 03:08:19 nrt Exp $
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41
private i_str_t *searchPattern = NULL;
42
private ic_t firstLetter;
44
private boolean_t FindCheck( line_t *line )
46
int i, iptr, cptr, tptr, hptr;
48
for( hptr = 0 ; hptr < line->heads ; hptr++ )
49
line->head[ hptr ].hit = FALSE;
52
for( iptr = 0 ; NOSET != line->istr[ iptr ].charset ; iptr++ ){
53
if( firstLetter == line->istr[ iptr ].c ){
54
for( cptr = iptr, tptr = 0 ; NOSET != searchPattern[ tptr ].charset ; tptr++, cptr++ ){
55
if( line->istr[ cptr ].c != searchPattern[ tptr ].c )
57
if( searchPattern[ tptr ].charset != line->istr[ cptr ].charset )
63
while( iptr >= line->head[ hptr ].ptr )
65
line->head[ hptr ].hit = TRUE;
66
for( i = iptr ; i < cptr ; i++ )
67
line->istr[ i ].attr |= ATTR_STANDOUT;
74
return line->head[ hptr ].hit;
77
private boolean_t FindOnly( i_str_t *istr )
81
for( iptr = 0 ; NOSET != istr[ iptr ].charset ; iptr++ ){
82
if( firstLetter == istr[ iptr ].c ){
83
for( cptr = iptr, tptr = 0 ; NOSET != searchPattern[ tptr ].charset ; tptr++, cptr++ ){
84
if( searchPattern[ tptr ].c != istr[ cptr ].c )
86
if( searchPattern[ tptr ].charset != istr[ cptr ].charset )
98
private boolean_t FindCheckRegexp( line_t *line )
100
int i, iptr, cptr, hptr;
102
for( hptr = 0 ; hptr < line->heads ; hptr++ )
103
line->head[ hptr ].hit = FALSE;
106
for( iptr = 0 ; /* NOSET != line->istr[ iptr ].charset */ ; iptr++ ){
107
if( TRUE != regexp_short_cut
108
|| regexp_first_letter == ToLower( line->istr[ iptr ].charset,
109
line->istr[ iptr ].c ) ){
111
if( TRUE == ReRun( line->istr, &cptr ) ){
116
/* in case that pattern begins with '^' */
117
line->head[ hptr ].hit = TRUE;
118
line->istr[ iptr ].attr |= ATTR_STANDOUT;
120
while( iptr >= line->head[ hptr ].ptr )
122
line->head[ hptr ].hit = TRUE;
123
for( i = iptr ; i <= cptr ; i++ )
124
line->istr[ i ].attr |= ATTR_STANDOUT;
127
} else if( NOSET == line->istr[ cptr ].charset )
130
if( NOSET == line->istr[ iptr ].charset )
134
return line->head[ hptr ].hit;
137
private boolean_t FindOnlyRegexp( i_str_t *istr )
141
for( iptr = 0 ; /* NOSET != istr[ iptr ].charset */ ; iptr++ ){
142
if( TRUE != regexp_short_cut
143
|| regexp_first_letter == ToLower( istr[ iptr ].charset,
146
if( TRUE == ReRun( istr, &cptr ) )
148
else if( NOSET == istr[ cptr ].charset )
151
if( NOSET == istr[ iptr ].charset )
158
public void FindSetup()
160
if( TRUE == regexp_search ){
161
find_func = FindCheckRegexp;
162
find_only_func = FindOnlyRegexp;
164
find_func = FindCheck;
165
find_only_func = FindOnly;
169
private void FindReset( file_t *f )
175
for( i = 0 ; i < BLOCK_SIZE ; i++ ){
176
if( TRUE == f->used[ i ] ){
177
for( j = 0 ; j < f->page[ i ].lines ; j++ ){
178
line = &f->page[ i ].line[ j ];
180
for( k = 0 ; NOSET != istr[ k ].charset ; k++ ){
181
if( CNTRL != istr[ k ].charset )
182
istr[ k ].attr &= ~ATTR_STANDOUT;
184
if( NULL != f->find.pattern )
185
(*find_func)( line );
191
public boolean_t FindClearPattern( file_t *f )
193
if( NULL != f->find.pattern ){
194
IstrFree( f->find.pattern );
195
f->find.pattern = NULL;
196
searchPattern = NULL;
205
public byte *FindResetPattern( file_t *f, i_str_t *istr )
209
AdjustPatternCharset( f->inputCodingSystem, f->keyboardCodingSystem,
210
f->defaultCodingSystem, istr );
212
searchPattern = istr;
213
firstLetter = searchPattern[ 0 ].c;
215
f->find.pattern = istr;
217
if( TRUE == regexp_search ){
218
if( NULL != (res = ReMakeDFA( istr )) ){
219
IstrFree( f->find.pattern );
220
f->find.pattern = NULL;
221
searchPattern = NULL;
228
public byte *FindSetPattern( file_t *f, i_str_t *istr )
232
if( NULL != f->find.pattern )
233
IstrFree( f->find.pattern );
235
f->find.first = TRUE;
236
f->find.pos = f->screen.top;
238
res = FindResetPattern( f, istr );
245
private boolean_t FindContinue( file_t *f, position_t *pos, boolean_t forward )
248
unsigned int segment;
249
int offset, foundOffset = 0;
251
boolean_t simple, res, found;
259
while( FALSE == f->eof ){
260
if( FALSE == FileSeek( f, segment ) )
263
if( TRUE == allow_interrupt )
266
if( TRUE == kb_interrupted )
268
for( offset = 0 ; offset < PAGE_SIZE && FALSE == f->eof ; offset++ ){
269
str = FileLoadLine( f, &idx, &simple );
274
istr = DecodeSimple( IstrAlloc( ZONE_FREE, idx + 1 ),
277
istr = Decode( IstrAlloc( ZONE_FREE, idx + 1 ),
278
f->inputCodingSystem, str, &idx );
281
res = (*find_only_func)( istr );
285
if( TRUE == forward ){
291
foundOffset = offset;
295
if( TRUE == forward ){
300
pos->off = foundOffset;
313
public int FindForward( file_t *f )
315
boolean_t flagFind, flagContinue;
319
PositionAssign( pos, f->find.pos );
321
if( FALSE == f->find.first ){
322
flagContinue = FALSE;
324
PositionInc( f, pos.seg, pos.blk, pos.off, pos.phy );
328
if( FALSE == flagContinue )
331
if( FALSE == FetchLine( f, pos.seg, pos.off ) )
333
f->find.first = FALSE;
336
ConsoleEnableInterrupt();
338
flagContinue = FALSE;
342
* $B%-%c%C%7%eFb$N%5!<%A(B
346
if( TRUE == allow_interrupt )
349
if( TRUE == kb_interrupted )
351
if( TRUE == f->page[ pos.blk ].line[ pos.off ].head[ pos.phy ].hit ){
355
if( ++pos.phy >= f->page[ pos.blk ].line[ pos.off ].heads ){
356
if( ++pos.off >= f->page[ pos.blk ].lines ){
358
pos.blk = Block( pos.seg );
359
if( TRUE == f->used[ pos.blk ]
360
&& pos.seg == f->page[ pos.blk ].segment ){
373
* $B%-%c%C%7%e30$N%5!<%A(B
375
if( TRUE == flagContinue ){
376
if( TRUE == FindContinue( f, &pos, TRUE ) ){
377
ConsoleDisableInterrupt();
378
ScreenTop( f, 1 + pos.seg * PAGE_SIZE + pos.off );
379
PositionAssign( pos, f->screen.top );
380
while( FALSE == f->page[ pos.blk ].line[ pos.off ].head[ pos.phy ].hit ){
381
PositionInc( f, pos.seg, pos.blk, pos.off, pos.phy );
383
ScreenTopPhysical( f, &pos );
388
ConsoleDisableInterrupt();
390
if( TRUE == flagFind ){
391
ScreenTopPhysical( f, &pos );
394
PositionAssign( pos, f->find.pos ); /* for MSDOS */
395
ScreenTopPhysical( f, &pos );
400
public int FindBackward( file_t *f )
402
boolean_t flagFind, flagContinue;
406
PositionAssign( pos, f->find.pos );
408
if( FALSE == f->find.first ){
409
flagContinue = FALSE;
411
PositionDec( f, pos.seg, pos.blk, pos.off, pos.phy );
415
if( FALSE == flagContinue )
418
if( FALSE == FetchLine( f, pos.seg, pos.off ) )
420
f->find.first = FALSE;
423
ConsoleEnableInterrupt();
425
flagContinue = FALSE;
429
* $B%-%c%C%7%eFb$N%5!<%A(B
433
if( TRUE == allow_interrupt )
436
if( TRUE == kb_interrupted )
438
if( TRUE == f->page[ pos.blk ].line[ pos.off ].head[ pos.phy ].hit ){
450
pos.blk = Block( pos.seg );
451
if( TRUE == f->used[ pos.blk ]
452
&& pos.seg == f->page[ pos.blk ].segment ){
453
pos.off = f->page[ pos.blk ].lines - 1;
459
pos.phy = f->page[ pos.blk ].line[ pos.off ].heads - 1;
465
* $B%-%c%C%7%e30$N%5!<%A(B
467
if( TRUE == flagContinue ){
468
if( TRUE == FindContinue( f, &pos, FALSE ) ){
469
ConsoleDisableInterrupt();
470
ScreenTop( f, 1 + pos.seg * PAGE_SIZE + pos.off );
471
PositionAssign( pos, f->screen.top );
472
pos.phy = f->page[ pos.blk ].line[ pos.off ].heads - 1;
473
while( FALSE == f->page[ pos.blk ].line[ pos.off ].head[ pos.phy ].hit ){
474
PositionDec( f, pos.seg, pos.blk, pos.off, pos.phy );
476
ScreenTopPhysical( f, &pos );
481
ConsoleDisableInterrupt();
483
if( TRUE == flagFind ){
484
ScreenTopPhysical( f, &pos );
487
PositionAssign( pos, f->find.pos ); /* for MSDOS */
488
ScreenTopPhysical( f, &pos );