
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
|
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&
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
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)
|