OBJNAM TRIM.SBR ; 6 May 83, edited 9-Dec-85
; Subroutine to strip leading and trailing whitespace from strings
; by Irv Bromberg, Medic/OS Consultants, Toronto, Canada
RADIX 10
VMAJOR=3
VMINOR=2
VSUB=0
VEDIT=13

IF EQ,1
Edit history
9-May-83  added tab stipping
30-Apr-85 added INTERN to TRIM for use with XBASIC
         (simply LNKLIT TRIM after assembling)
30-Nov-85 major re-write: DBF loops, strip all whitespace, more efficient
9-Dec-85  rename to TRIM.SBR to prevent conflict with Alpha's STRIP.SBR

Calling syntax: XCALL TRIM,list-of-variables-to-trim
strings and unformatted variables are trimmed of leading and trailing
whitespace (spaces, control codes), numeric variables are not changed

Note how this subroutine differs from commonly available routines that
are similar:

       any number of variables can be passed for stripping
       trims all whitespace (spaces or any control codes)

The control-code trimming capability is useful in advanced terminal
input/output, making it easy to get rid of leading or trailing control
codes that are not desired.  This is especially useful when special
terminal input/output causes one or more NULL codes to be placed into
the start of a string, preventing the following non-NULL characters
in the string from being seen by BASIC -- TRIM.SBR removed such leading
NULL(s) and shifts the printable characters down to start at the first
byte position.

ENDC

SEARCH SYS
SEARCH SYSSYM

String=A2
Scan=A3
Atemp=A6

Char=D1
Pcount=D2
Size=D3
Vtype=D4
Dtemp=D6

SPACE=32

INTERN TRIM

TRIM:   PHDR    -1,0,PH$REE!PH$REU

       MOVW    (Scan)+,Pcount          ; get #variables
       BR      NextVar

Loop:   MOVW    (Scan)+,Vtype           ; get variable type
       MOV     (Scan)+,String          ; and address
       MOV     (Scan)+,Size            ; and size
       BEQ     NextVar                 ; skip var with NULL dimension
       CMPW    Vtype,#2                ; check if string or unformatted
       BLOS    DoIt                    ; bypass numeric variables
NextVar:DBF     Pcount,Loop
       RTN                             ; Done, return to BASIC

DoIt:   LEA     Atemp,0(String)[~Size]  ; point to last byte
       MOVW    Size,Dtemp
       BR      eClrEnd                 ; enter at end of DBF loop

ClrEnd: MOVB    -(Atemp),Char           ; nothing to clear if already NULL
       BEQ     eClrEnd
       CMPB    Char,#SPACE             ; is this whitespace?
       BHI     Begin                   ; no, now check beginning
       CLRB    (Atemp)                 ; clear whitespace to null
eClrEnd:DBF     Dtemp,ClrEnd
       BR      NextVar                 ; goto next var because string empty

Begin:  MOV     Size,Dtemp              ; search for first non-whitespace
       MOV     String,Atemp            ; character in the string
       DECW    Dtemp                   ; pre-decr for DBHI loop
10$:    CMPB    (Atemp)+,#SPACE         ; (empty string impossible here)
       DBHI    Dtemp,10$               ; stop at first printable character
       DECW    Atemp                   ; backup
       CMP     Atemp,String            ; non-whitespace at first position?
       BEQ     NextVar                 ; yes, nothing to move
20$:    MOVB    (Atemp)+,(String)+      ; move everything down
       DBEQ    Dtemp,20$               ; stop at NULL
       MOV     Atemp,Dtemp             ; calculate distance we shifted down
       SUB     String,Dtemp
       BR      40$                     ; enter at end of DBF loop
30$:    CLRB    (String)+               ; clear in-between part
40$:    DBF     Dtemp,30$
       BR      NextVar

       ASMMSG  "Now execute the command:  LNKLIT TRIM  to finish up"

       END