FB II Compiler

PG PRO

Debugging

Memory

System

Mathematics

Resources

Disk I/O

Windows

Controls

Menus

Mouse

Keyboard

Text

Fonts

Drawing

Sound

Clipboard

Printing

Communication

ASM

Made with FB

TEXT

Search for characters


I'm sure there are faster methods, but this function works, is reasonably fast, and has been heavily tested:

LOCAL FN findCaseInsensitive&(hndl&,theText$,start&)
' hndl& is the handle to the text you want searched
' theText$ is the text you want found
' start& is the offset into the handle you want to start searching at; 0 starts at the beginning
' returns the found offset or -1 if not found
  DIM temp$, x&, y, found&, size&, c
  found& = -1
  POKE @temp$, LEN(theText$)
  size& = FN GETHANDLESIZE(hndl&) - LEN(theText$) + 1
  LONG IF start& < size& ' are we starting inside the handle?
    x& = start&
    theText$ = UCASE$(theText$) ' convert the text to find to uppercase
    c = ASC(theText$) ' first character of theText$
    DO
      y = PEEK([hndl&]+x&) ' 'first character of the chunk we are looking at in the handle
      IF y >= _"a" AND y <= _"z" THEN y = y - 32
      LONG IF c = y ' do the first characters match (case-insensitive)?
' if so, lets compare the rest:
        BLOCKMOVE [hndl&]+x&, @temp$+1, LEN(theText$)
        IF theText$ = UCASE$(temp$) THEN found& = x& : x& = size& - 1
      END IF
      INC(x&)
    UNTIL found& > -1 OR x& = size&
  END IF
END FN = found&

Greg


When I needed to do case insens searching I converted the text I'm searching for to upperCase and did the same to the text I'm searching through.

Then I used FN MUNGER to do the search, because it's faster than anything I could come up with.

Here's some code of mine...

I hope there's no errors/bugs

'=========================

CLEAR LOCAL
  DIM txtHndl&
LOCAL FN ftConvertMoreThan32Kb(txtHndl&)
  DIM loop&, hndlLen&, err, 255 theTxt$, chunk
  DIM theTxtPtr&, textLen

  theTxtPtr& = @theTxt$ + 1

  hndlLen& = FN GETHANDLESIZE(txtHndl&)
  err = FN HLOCK(txtHndl&) 'cause it's a hndl lock it down
'now get the text in the hndl in 255 character chunks
'and convert to upperCase, and then put it back in the
'hndl over the top of it's self
  WHILE loop& < hndlLen&
    IF loop& + 255 < hndlLen& THEN chunk = 255 ELSE chunk = hndlLen& - loop&
    BLOCKMOVE [txtHndl&] + loop&, @theTxt$+1, chunk
    POKE @theTxt$, chunk

    textLen = PEEK(@theTxt$)
    LONG IF textLen

      ` MOVE.L ^theTxtPtr&,-(SP) ;Ptr
      ` MOVE.W ^textLen,-(SP) ;INTEGER
      ` DC.W $301F,$205F,$A054 ;UprString

    END IF

    BLOCKMOVE @theTxt$+1, [txtHndl&] + loop&, chunk
    loop& = loop& + chunk
  WEND
  err = FN HUNLOCK(txtHndl&) 'now unlock the handl
END FN

'=========================

'these FNs can work on text upto 32kb in size

LOCAL MODE
  DIM textPtr&, theLen%
LOCAL FN UppercaseText(textPtr&, theLen%)
  ` move.l ^textPtr&,-(sp) ;Ptr
  ` move.w ^theLen%,-(sp) ;INTEGER
  ` dc.w $301F,$205F,$A456
  ` ext.l d0 ;error returned in d0
END FN REM END FN passes the error result stored in d0 automatically

LOCAL MODE
  DIM textPtr&, theLen%
LOCAL FN StripDiac(textPtr&, theLen%)
  ` move.l ^textPtr&,-(sp) ;Ptr
  ` move.w ^theLen%,-(sp) ;INTEGER
  ` dc.w $301F,$205F,$A256
  ` ext.l d0 ;error returned in d0
END FN REM END FN passes the error result stored in d0 automatically

LOCAL MODE
  DIM textPtr&, theLen%
LOCAL FN UppercaseStripDiacritics(textPtr&, theLen%)
  ` move.l ^textPtr&,-(sp) ;Ptr
  ` move.w ^theLen%,-(sp) ;INTEGER
  ` dc.w $301F,$205F,$A656
  ` ext.l d0 ;error returned in d0
END FN REM END FN passes the error result stored in d0 automatically

'=========================

LOCAL
  DIM convertMode, txtH&
LOCAL FN ftConvertText(convertMode, txtH&)
  DIM err, osErr, theLen&

  gSearchTxt$ = UCASE$(gSearchTxt$)

  theLen& = FN GETHANDLESIZE(txtH&)

  LONG IF theLen& < 32767
    err = FN HLOCK(txtH&)

    SELECT convertMode
      CASE _CaseItem
        osErr = FN UppercaseText([txtH&], theLen&)
      CASE _CaseDiacriticalItem
        osErr = FN UppercaseStripDiacritics([txtH&], theLen&)
      CASE _DiacriticalMarksItem
        osErr = FN StripDiac([txtH&], theLen&)
    END SELECT

    err = FN HUNLOCK(txtH&)

    IF osErr <> _noErr THEN FN ftError(osErr)

  XELSE
    FN ftConvertMoreThan32Kb(txtH&)
  END IF
END FN = osErr

Pete..


This copies, then ucases a handle.


LOCAL
  DIM hndl&,ptr&,size&
  DIM err,endPtr&
LOCAL FN ucaseHndl(origHndl&)
  hndl& = FN HANDTOHAND(origHndl&)
  LONG IF hndl&
    size& = FN GETHANDLESIZE(hndl&)

    ptr& = [hndl&]
    endPtr& = ptr& + size& - 1

    FOR ptr& = ptr& TO endPtr&
      LONG IF PEEK(ptr&) => _"a"
        LONG IF PEEK(ptr&) <= _"z"
          POKE ptr&,PEEK(ptr&)-32
        END IF
      END IF
    NEXT
  XELSE
    hndl& = origHndl&
  END IF

END FN = hndl&


From there, you only need use munger...

offset& = FN MUNGER(destStrH&,offset&,findStr&,findLen,0,0)

STAZ ~)~