\*
 *   ZEN 1.10  Supplementary string package
 *     C 1990  by Martin Tracy
 *             Last modified  1.1.90
 *\

| 1024 CONSTANT #SB   \ Rotating string buffer size in bytes.
                      \ Also maximum length of string.

| VARIABLE SB      \ Rotating string buffer.
  1024 ( #SB) CELL - ALLOT

\ Allocate u bytes in rotating buffer and return its address.
| : SBALLOT ( u - a)
   #SB OVER SBCTR @ + U< ( wrap?)
   IF  SBCTR OFF  THEN  SB SBCTR @ +  SWAP SBCTR +! ;

\ Copy or renew temporary string.
: STRCPY ( a u - a2 u2)
   DUP SBALLOT  SWAP 2DUP 2>R MOVE  2R> ;

\ Copy string and concatenate string2 to copy.
: STRCAT ( a u a2 u2 - a3 u3)
   2>R  DUP R@ +  DUP SBALLOT  2>R  R@ SWAP MOVE  2R> SWAP
   2R>  2OVER  ROT OVER SWAP - /STRING MOVE ;


\ Return -1 if string a1 n < a2 n , 0 if equal, and 1 if >.
CODE -TEXT ( a1 len a2 - -1|0|1)
        mov   di,bx
        mov   bx,ds
        mov   es,bx
        xchg  ax,si
        pop   cx
        pop   si
        jcxz  MTex1
        repe  cmpsb
        jz    MTex1
        mov   cx,1
        jnc   MTex1
        neg   cx
MTex1:  mov   bx,cx
        xchg  ax,si
        NEXT
END-CODE

\ Return -1 if a n < a2 n2 , 0 if equal, and 1 if >.
: COMPARE ( a n a2 n2 - -1|0|1)
   ROT  2DUP ( lengths ) 2>R  MIN SWAP  -TEXT  DUP
   IF    2R> 2DROP
   ELSE  DROP  2R> 2DUP = ( lengths = ?)
     IF  2DROP 0  ELSE  > 2* 1+  THEN
   THEN ;


\ Return the position of string2 in string1.
\ Offset is zero if string2 is found in first char position.
\ Return -1 if no match.
CODE STRNDX ( a u a2 u2 - offset | -1)
        mov   dx,si
        pop   si
        pop   ax
        xchg  ax,bx
        pop   di      ; si=a2 ax=u2 di=a1 bx=u1
        push  dx
        or    ax,ax
        jnz   Strnd1
        pop   si
        sub   bx,bx
        NEXT
Strnd1: sub   bx,ax
        jns   Strnd2
        pop   si
        mov   bx,TRUTH
        NEXT
Strnd2: push  di
        mov   dx,ds
        mov   es,dx
Strnd3: push  si
        push  di
        mov   cx,ax
        repe  cmpsb
        pop   di
        pop   si
        jnz   Strnd4
        pop   si
        sub   di,si
        pop   si
        mov   bx,di
        NEXT
Strnd4: or    bx,bx
        jz    Strnd5
        inc   di
        dec   bx
        jmp   Strnd3
Strnd5: pop   di
        pop   si
        mov   bx,TRUTH
        NEXT
END-CODE


\*
\ Return -1 if string a1 n < a2 n , 0 if equal, and 1 if >.
: -TEXT ( a1 n a2 - -1|0|1)
   SWAP 0 ?DO  OVER C@ OVER C@ - ( these chars <> ?)
             IF  UNLOOP  C@ SWAP C@ > 2* 1+  EXIT  THEN  1 1 D+
          LOOP  2DROP 0 ;


\ Return the position of string2 in string1.
\ Offset is zero if string2 is found in first char position.
\ Return -1 if no match.
: STRNDX ( a u a2 u2 - offset | -1)
   DUP 0= IF       2DROP 2DROP     0 EXIT  THEN
   2SWAP  2 PICK OVER SWAP -   ( a2 u2 a u u-u2)
   DUP 0< IF  DROP 2DROP 2DROP  TRUE EXIT  THEN
   0   ( offset) SWAP 1+ 0
   DO  ( offset) >R            ( a2 u2 a u  r: o)
     2OVER 2OVER DROP  -TEXT 0=  ( equal? )
     IF  2DROP 2DROP  R>  UNLOOP EXIT  THEN
     1 /STRING   R> 1+
   LOOP  DROP 2DROP 2DROP  TRUE ;
*\

