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.