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

Quickly strip spaces from a string


I threw this function together, partly because I might need it but mostly for fun. Do you have any suggestions on how it can be improved?
----- Begin code example -----

'_____ Header ______________________________________
COMPILE 0, _CaseInsensitive _DimmedVarsOnly _NoRedimVars
WINDOW OFF
END GLOBALS

'_____ Functions ___________________________________
LOCAL MODE
'Length% = FN StripSpacesFromString (StringPtr&)
'
'Length%        the new length of the string
'StringPtr&     a pointer to a pascal string
'
'When called StripSpacesFromString strips all spaces from the beginning
'and end of a pascal string, just like the name implies. Not as fast as
'DEF TRUNCATE.
'
LOCAL FN StripSpacesFromString (StrPtr&)
  `     move.l  ^StrPtr&,a0
  `     clr.l   d0
  `     move.b  (a0)+,d0
  `     beq     ssend           ;branch to end if length = 0
  `ssloop1                      ;remove spaces from end of string
  `     cmpi.b  #$20,$FF(a0,d0.b)
  `     bne     ssdone1
  `     sub.b   #$01,d0
  `     beq     ssend           ;branch to end if length = 0
  `     bra     ssloop1
  `ssdone1
  `     move.l  a0,a1
  `ssloop2                      ;count spaces at beginning of string
  `     cmpi.b  #$20,(a1)
  `     bne     ssdone2
  `     sub.b   #$01,d0
  `     addq.l  #$01,a1
  `     bra     ssloop2
  `ssdone2
  `     cmpa.l  a0,a1
  `     beq     ssend
  `     move.l  a0,a2
  `     move.b  d0,d1
  `ssloop3                      ;remove spaces from beginning of string
  `     move.b  (a1)+,(a2)+
  `     sub.b   #$01,d1
  `     bne     ssloop3
  `ssend
  `     move.b  d0,-(a0)
END FN

LOCAL FN PrintExample (TheStr$)
  DIM TheTime&, Count&, NewStr$

  PRINT """ + TheStr$ + """;

  TheTime& = FN TICKCOUNT
  FOR Count& = 1 TO 25000
    NewStr$ = TheStr$
    FN StripSpacesFromString (@NewStr$)
  NEXT
  TheTime& = FN TICKCOUNT - TheTime&

  PRINT TAB(28) """ + NewStr$ + """ TAB (55) TheTime& "ticks"
END FN

'_____ Main ________________________________________

DIM Count%, TheStr$

WINDOW 1
TEXT _monaco,9

CALL SETORIGIN (-3,-3)

PRINT "Before" TAB(28) "After" TAB(56) "Time to call 25000 times"

COLOR _zblue

FOR Count% = 0 TO 10
  TheStr$ = SPACE$(Count%) + "FutureBASIC II" + SPACE$(10-Count%)
  FN PrintExample (TheStr$)
NEXT
TheStr$ = SPACE$(24)
FN PrintExample (TheStr$)
TheStr$ = STRING$(24,&7A)
FN PrintExample (TheStr$)

PRINT CHR$(&0d) CHR$(&0d) CHR$(&0d)

COLOR _zblack
PRINT "(Press any key to continue)"

CALL SETORIGIN (0,0)

DO: UNTIL LEN(INKEY$)
Pontus Ilbring

There is one semi-mistake in your code. The line
  cmpi.b  #$20,$FF(a0,d0.b)
is not a valid 68K instruction, but is accepted by FB and assembled to
  cmpi.b  #$20,$FF(a0,d0.w)
The following version of your routine is shorter, uses fewer labels, and is possibly clearer. By use of dbXX instructions, all 3 loops have been reduced to minimum length. It is therefore a little faster, although I defy anyone to find a circumstance in which that could matter :-)
LOCAL FN StripSpacesFromString (StrPtr&)
' call like this:  FN StripSpacesFromString (@anyString$)
 _spaceChr=32
 `     movea.l ^StrPtr&,a0
 `     clr.w    d0
 `     move.b   (a0)+,d0
 `     beq.s    ssend     ; branch to end if length = 0
 `     subq.w  #1,d0      ; adjust length for dbne
 `ssloop1                 ; count trailing spaces
 `     cmpi.b  #spaceChr,(a0,d0.w)
 `     dbne     d0,ssloop1
 `     beq.s    ssend     ; branch to end if length now = 0
 `     movea.l  a0,a1
 `ssloop2                 ; count leading spaces
 `     cmpi.b  #spaceChr,(a1)+
 `     dbne     d0,ssloop2
 `     subq.l  #1,a1
 `     cmpa.l   a0,a1
 `     beq.s    ssend     ; branch if none
 `     movea.l  a0,a2
 `     move.w   d0,d1
 `ssloop3                 ; remove leading spaces
 `     move.b   (a1)+,(a2)+
 `     dbra     d1,ssloop3
 `ssend
 `     addq.w  #1,d0
 `     move.b   d0,-(a0)
END FN
In fact, on my machine your timing loop:
  TheTime& = FN TICKCOUNT
  FOR Count& = 1 TO 50000
   NewStr$ = TheStr$
   FN StripSpacesFromString (@NewStr$)
  NEXT
  TheTime& = FN TICKCOUNT - TheTime&
is dominated by FB's slow copying of the string, and to show a real difference in speed between the two versions of FN StripSpacesFromString I had to copy the strings in assembler too. The moral is that your routine is plenty fast enough.
Robert Purves