ftp.nice.ch/pub/next/text/apps/eText5.0.93.s.tar.gz#/eText5/eText.subproj/MiscSearchText.m

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.