This is MiscSearchText.m in view mode; [Download] [Up]
{\rtf0\ansi{\fonttbl\f0\fmodern Courier;\f2\fmodern Ohlfs;}
\margl40
\margr40
\pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\f0\b0\i0\ulnone\fs24\fc0\cf0 /*\
* Copyright (c) 1993 Christopher J. Kane. All rights reserved.\
*\
* This software is subject to the terms of the MiscKit license\
* agreement. Refer to the license document included with the\
* MiscKit distribution for these terms.\
*\
* Version: 1.2 (22 March 1994)\
*/\
\
#import "
\b MiscSearchText.h
\b0 "\
#import "
\b Kludges
\b0 .subproj/
\b regexpr.h
\b0 "\
#import "
\b Kludges
\b0 .subproj/
\b MiscTBMK.h
\b0 "\
\
@implementation
\b eText
\b0 (SearchText)\
\
- (oneway void)makeSelectionVisible\
\{\
[self scrollSelToVisible];\
\}\
\
- (int)replaceAll:(const char *)pattern with:(const char *)replacement mode:(SearchMode)mode regexpr:(BOOL)regexpr cases:(BOOL)cases\
\{\
unsigned char fm[256], tr[256];\
struct re_pattern_buffer rpat;\
Misc_TBMKpattern lpat=NULL;\
NXStream *in_strm=NULL, *out_strm=NULL;\
int s1=0, e1=0, s2=0, e2=0, ret_val, plen, rlen, pos, searchTextMaxSize;\
\
if (sp0.cp<0 && mode!=TextEdgeToTextEdge)\
return SEARCH_NO_SELECTION;\
if (![self isEditable])\
return SEARCH_CANNOT_WRITE;\
switch (mode)\
\{\
case TextEdgeToTextEdge:\
case SelStartToSelStart:\
case SelEndToSelEnd: s1 = 0; e1 = textLength; break;\
case TextEdgeToSelStart: s1 = 0; e1 = sp0.cp; break;\
case TextEdgeToSelEnd: s1 = 0; e1 = spN.cp; break;\
case SelStartToSelEnd: s1 = sp0.cp; e1 = spN.cp-sp0.cp; break;\
case SelStartToTextEdge: s1 = sp0.cp; e1 = textLength-sp0.cp; break;\
case SelEndToTextEdge: s1 = spN.cp; e1 = textLength-spN.cp; break;\
case SelEndToSelStart: s1 = 0; e1 = sp0.cp; s2 = spN.cp; e2 = textLength-spN.cp; break;\
default: return SEARCH_INVALID_ARGUMENT;\
\}\
searchTextMaxSize = s1+e1;\
plen = strlen(pattern);\
rlen = strlen(replacement);\
if (regexpr)\
\{\
char *str;\
int i;\
memset(&rpat, 0, sizeof(rpat));\
for(i=256; i--;)\
tr[i] = i;\
if (!cases)\
for(i='A'; i<='Z'; i++) tr[i] = i-'A'+'a';\
rpat.translate = tr;\
rpat.fastmap = fm;\
str = re_compile_pattern((char *)pattern, plen, &rpat);\
if (str!=NULL)\
return (strcmp(str, "Out of memory")?SEARCH_INVALID_REGEXPR:SEARCH_INTERNAL_ERROR);\
\}\
else\
\{\
lpat = Misc_TBMKpattern_alloc(pattern, plen, 0, !cases);\
if (lpat==NULL)\
return SEARCH_INTERNAL_ERROR;\
\}\
out_strm = NXOpenMemory(NULL, 0, NX_READWRITE);\
in_strm = NXOpenMemory(NULL, 0, NX_READWRITE);\
if (out_strm==NULL || in_strm==NULL)\
\{\
ret_val = SEARCH_INTERNAL_ERROR;\
goto exit;\
\}\
[self writeText:in_strm];\
NXSeek(in_strm, 0, NX_FROMSTART);\
ret_val = 0;\
NXWrite(out_strm, in_strm->buf_base, s1); /* get up to start of searching */\
/* invariant for searching: in_strm->buf_base+s1+e1 is the position _after_ the last one searched */\
start_searching:\
if (regexpr)\
\{\
while (!NXUserAborted() && e1>0 && (pos = re_search_pattern(&rpat, in_strm->buf_base, searchTextMaxSize, s1, e1, 0))>=0)\
\{\
int len = re_match_pattern(&rpat, in_strm->buf_base, searchTextMaxSize, pos, 0);\
if (len<0)\
\{\
ret_val = SEARCH_INTERNAL_ERROR;\
goto exit;\
\}\
NXWrite(out_strm, in_strm->buf_base+s1, pos-s1);\
NXWrite(out_strm, replacement, rlen);\
e1 -= (pos-s1+len);\
s1 = (pos+len);\
ret_val++;\
\}\
if (pos==-2)\
\{\
ret_val = SEARCH_INTERNAL_ERROR;\
goto exit;\
\}\
\}\
else\
\{\
while (!NXUserAborted() && e1>0 && Misc_TBMKsearch_memory(lpat, in_strm->buf_base+s1, e1, 0, &pos)>0)\
\{\
NXWrite(out_strm, in_strm->buf_base+s1, pos);\
NXWrite(out_strm, replacement, rlen);\
s1 += (pos+plen);\
e1 -= (pos+plen);\
ret_val++;\
\}\
\}\
if (NXUserAborted())\
\{\
ret_val = SEARCH_ABORTED;\
goto exit;\
\}\
if (e1>0)\
NXWrite(out_strm, in_strm->buf_base+s1, e1); /* get remainder of searched material */\
if (e2!=0)\
\{\
NXWrite(out_strm, in_strm->buf_base+s1+e1, s2-(s1+e1)); /* get gap */\
s1 = s2;\
e1 = e2;\
s2 = e2 = 0;\
goto start_searching;\
\}\
NXWrite(out_strm, in_strm->buf_base+s1+e1, textLength-(s1+e1)); /* after searched to end */\
NXSeek(out_strm, 0, NX_FROMSTART);\
[self readText:out_strm];\
[self setSel:0 :0];\
exit:\
Misc_TBMKpattern_free(&lpat);\
if (in_strm!=NULL)\
NXCloseMemory(in_strm, NX_FREEBUFFER);\
if (out_strm!=NULL)\
NXCloseMemory(out_strm, NX_FREEBUFFER);\
return ret_val;\
\}\
\
- (oneway void)replaceSelection:(const char *)replacement\
\{\
if ([self isEditable])\
[self replaceSel:replacement];\
\}\
\
- (int)searchFor:(const char *)pattern mode:(SearchMode)mode reverse:(BOOL)rev regexpr:(BOOL)regexpr cases:(BOOL)cases position:(out int *)pos size:(out int *)size\
\{\
unsigned char fm[256], tr[256];\
struct re_pattern_buffer rpat;\
Misc_TBMKpattern lpat=NULL;\
NXStream *in_strm=NULL;\
int s1=0, e1=0, s2=0, e2=0, ret_val, plen, p, position;\
\
if (sp0.cp<0 && mode!=TextEdgeToTextEdge)\
return SEARCH_NO_SELECTION;\
if (rev)\
switch (mode)\
\{\
case TextEdgeToSelStart: s1 = textLength-1; e1 = sp0.cp-textLength; break;\
case TextEdgeToSelEnd: s1 = textLength-1; e1 = spN.cp-textLength; break;\
case TextEdgeToTextEdge: s1 = textLength-1; e1 = -textLength; break;\
case SelStartToSelEnd: s1 = sp0.cp-1; e1 = -sp0.cp+1; s2 = textLength-1; e2 = spN.cp-textLength+1; break;\
case SelStartToTextEdge: s1 = sp0.cp-1; e1 = -sp0.cp+1; break;\
case SelStartToSelStart: s1 = sp0.cp-1; e1 = -sp0.cp+1; s2 = textLength-1; e2 = sp0.cp-textLength+1; break;\
case SelEndToTextEdge: s1 = spN.cp-1; e1 = -spN.cp+1; break;\
case SelEndToSelStart: s1 = spN.cp-1; e1 = sp0.cp-spN.cp+1; break;\
case SelEndToSelEnd: s1 = spN.cp-1; e1 = -spN.cp+1; s2 = textLength-1; e2 = spN.cp-textLength+1; break;\
default: return SEARCH_INVALID_ARGUMENT;\
\}\
else\
switch (mode)\
\{\
case TextEdgeToSelStart: s1 = 0; e1 = sp0.cp; break;\
case TextEdgeToSelEnd: s1 = 0; e1 = spN.cp; break;\
case TextEdgeToTextEdge: s1 = 0; e1 = textLength; break;\
case SelStartToSelEnd: s1 = sp0.cp; e1 = spN.cp-sp0.cp; break;\
case SelStartToTextEdge: s1 = sp0.cp; e1 = textLength-sp0.cp; break;\
case SelStartToSelStart: s1 = sp0.cp; e1 = textLength-sp0.cp; s2 = 0; e2 = sp0.cp; break;\
case SelEndToTextEdge: s1 = spN.cp; e1 = textLength-spN.cp; break;\
case SelEndToSelStart: s1 = spN.cp; e1 = textLength-spN.cp; s2 = 0; e2 = sp0.cp; break;\
case SelEndToSelEnd: s1 = spN.cp; e1 = textLength-spN.cp; s2 = 0; e2 = spN.cp; break;\
default: return SEARCH_INVALID_ARGUMENT;\
\}\
plen = strlen(pattern);\
if (regexpr)\
\{\
char *str;\
int i;\
memset(&rpat, 0, sizeof(rpat));\
for(i=256; i--;)\
tr[i] = i;\
if (!cases)\
for(i='A'; i<='Z'; i++) tr[i] = i-'A'+'a';\
rpat.translate = tr;\
rpat.fastmap = fm;\
str = re_compile_pattern((char *)pattern, plen, &rpat);\
if (str!=NULL)\
return (strcmp(str, "Out of memory")?SEARCH_INVALID_REGEXPR:SEARCH_INTERNAL_ERROR);\
\}\
else\
\{\
lpat = Misc_TBMKpattern_alloc(pattern, plen, rev, !cases);\
if (lpat==NULL)\
return SEARCH_INTERNAL_ERROR;\
\}\
in_strm = NXOpenMemory(NULL, 0, NX_READWRITE);\
if (in_strm==NULL)\
\{\
ret_val = SEARCH_INTERNAL_ERROR;\
goto exit;\
\}\
[self writeText:in_strm];\
NXSeek(in_strm, 0, NX_FROMSTART);\
ret_val = 0;\
start_searching:\
if (NXUserAborted())\
\{\
ret_val = SEARCH_ABORTED;\
goto exit;\
\}\
if (regexpr)\
\{\
p = -1;\
if (s1>=0)\
p = re_search_pattern(&rpat, in_strm->buf_base, textLength, s1, e1, 0);\
if (p==-1 && e2!=0)\
\{\
s1 = s2;\
e1 = e2;\
s2 = e2 = 0;\
goto start_searching;\
\}\
if (p==-2)\
\{\
ret_val = SEARCH_INTERNAL_ERROR;\
goto exit;\
\}\
if (p>-1)\
\{\
*pos = p;\
*size = re_match_pattern(&rpat, in_strm->buf_base, textLength, p, 0);\
if (*size<0)\
\{\
ret_val = SEARCH_INTERNAL_ERROR;\
goto exit;\
\}\
ret_val = 1;\
\}\
\}\
else\
\{\
p = 0;\
if (s1>=0)\
p = Misc_TBMKsearch_memory(lpat, in_strm->buf_base+s1, e1, 0, &position);\
if (p<0)\
\{\
ret_val = SEARCH_INTERNAL_ERROR;\
goto exit;\
\}\
if (p==0 && e2!=0)\
\{\
s1 = s2;\
e1 = e2;\
s2 = e2 = 0;\
goto start_searching;\
\}\
if (p>0)\
\{\
*pos = position+s1;\
*size = plen;\
ret_val = 1;\
\}\
\}\
exit:\
Misc_TBMKpattern_free(&lpat);\
if (in_strm!=NULL)\
NXCloseMemory(in_strm, NX_FREEBUFFER);\
return ret_val;\
\}\
\
- (oneway void)selectTextFrom:(int)start to:(int)end\
\{\
if ([self isSelectable] && start<=end && 0<=start)\
[self setSel:start :end];\
\}\
\
- (int)setRegExprSyntax:(int)syntax\
\{\
return re_set_syntax(syntax);\
\}\
\
///////////////////////////////////////////////////////////////////////////\
\b // RK, 10/22/94 Changed protocol name to use writeSearchableSelection....//\
\b0 ///////////////////////////////////////////////////////////////////////////\
- (void)
\b writeSearchableSelectionToPasteboard
\b0 :(in Pasteboard *)pboard asType:(in NXAtom)type\
\{\
char text[spN.cp-sp0.cp+1];\
[self getSubstring:text start:sp0.cp length:spN.cp-sp0.cp];\
text[spN.cp-sp0.cp] = '\\0';\
if (*text!='\\0')\
\{\
[pboard declareTypes:&type num:1 owner:NULL];\
[pboard writeType:type data:text length:spN.cp-sp0.cp];\
\}\
\}\
\
- (BOOL)
\b findText
\b0 :(const char *)
\b string
\b0
\b ignoreCase
\b0 :(BOOL)ignoreCaseflag
\b backwards
\b0 :(BOOL)backwardsflag
\b wrap
\b0 :(BOOL)wrapflag\
\{\
\b Misc_TBMKpattern
\b0
\b pat
\b0 ;\
\b int
\b0 s1, e1, s2, e2, mp, pos, r;\
\
s1 =
\b s2
\b0 = e1 =
\b e2
\b0 = 0;\
if (backwardsflag && sp0.cp<0)\
\{
\b s1
\b0 = textLength;
\b e1
\b0 = -textLength;\}\
else if (backwardsflag)\
\{
\b s1
\b0 = sp0.cp;
\b e1
\b0 = -sp0.cp;
\b s2
\b0 = textLength;
\b e2
\b0 = spN.cp-textLength;\}\
else if (sp0.cp<0)\
\{
\b s1
\b0 = 0;
\b e1
\b0 = textLength;\}\
else\
\{
\b s1
\b0 = spN.cp;
\b e1
\b0 = textLength-spN.cp;
\b s2
\b0 = 0;
\b e2
\b0 = sp0.cp;\}\
[self
\b stream
\b0 ];\
if (textStream==0)\
return
\b NO
\b0 ;\
\b pat
\b0 =
\b Misc_TBMKpattern_alloc
\b0 (
\b string
\b0 , strlen(string),
\b backwardsflag
\b0 ,
\b ignoreCaseflag
\b0 );\
if (pat==0)\
return
\b NO
\b0 ;\
\b NXSeek
\b0 (textStream,
\b s1
\b0 ,
\b NX_FROMSTART
\b0 );\
\b r
\b0 =
\b Misc_TBMKsearch_stream
\b0 (
\b pat
\b0 ,
\b textStream
\b0 ,
\b e1
\b0 , 0, &mp);\
\b pos
\b0 =
\b mp+s1
\b0 ;\
if (!r && e2>0 &&
\b wrapflag
\b0 ) \{\
\b NXSeek
\b0 (textStream,
\b s2
\b0 ,
\b NX_FROMSTART
\b0 );\
r =
\b Misc_TBMKsearch_stream
\b0 (pat, textStream, e2, 0, &mp);\
pos = mp+s2;\
\}\
\b Misc_TBMKpattern_free
\b0 (&
\b pat
\b0 );\
if (!r)\
return
\b NO
\b0 ;\
[self
\b setSel
\b0 :
\b pos
\b0 :pos+strlen(
\b string
\b0 )];\
[self
\b scrollSelToVisible
\b0 ];\
return
\b YES
\b0 ;\
\}\
@end\
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.