;/*****************************************************************************
;*
;* SOURCE FILE NAME = GTP.INC
;*
;* DESCRIPTIVE NAME = Get Token Ptr
;*
;* COPYRIGHT    COPYRIGHT IBM CORPORATION, 1991, 1992
;*              LICENSED MATERIAL - PROGRAM PROPERTY OF IBM
;*              REFER TO COPYRIGHT INSTRUCTION FORM#G120-2083
;*              RESTRICTED MATERIALS OF IBM
;*              IBM CONFIDENTIAL
;*
;* VERSION      V2.0
;*
;* DATE         07/12/91
;*
;* DESCRIPTION
;*              On Entry: - Pointer to Source Line
;*                        - Pointer to token to scan for
;*
;*              On Exit:  - Carry set if error, ES:SI undefined.
;*                        - No Carry, ES:SI points to first char after token.
;*              Registers:  ES destroyed
;*
;* FUNCTIONS    get_token_ptr,  toupper,        extract_parm,
;*              getnum,         itos,           itoa.
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*****************************************************************************/


;/***************************************************************************
;*
;* FUNCTION NAME = get_token_ptr
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

pubdeb          get_token_ptr
PROCEDURE       get_token_ptr   near

PARAMETER       token_ptr       dword
PARAMETER       target_ptr      dword
PARAMETER       source_ptr      dword

;*
;* DO NOT RE-ORDER THESE VARIABLES OR CHANGE STACK ARRANGEMENT IN THE CODE
;*

VARIABLE        token_strlen    word
VARIABLE        config_line     nbyte 255

BEGINPROC
                push    ds
                pusha
                cld
                les     di, token_ptr
                call    gtp_getlen
                jz      @F                      ; jif
                jmp     gtp_error
@@:             mov     token_strlen, cx
                les     di, source_ptr
                call    gtp_getlen
                jnz     gtp_error

;*
;* Transfer original line, converting to uppercase.
;*
                push    cx
                inc     cx                      ; include terminator
                lds     si, source_ptr          ; DS:SI -> config line
                xor     di, di
gtp_copy:       lodsb
                call    toupper
gtp_c1:         mov     config_line[di], al
                inc     di
                loop    gtp_copy
                pop     cx
;*
;* Find the required token.
;*
                lds     si, token_ptr           ; DS:SI -> token
                mov     ax, ss                  ;
                mov     es, ax                  ;
                lea     di, config_line
                mov     bx, si                  ; save copy
                lodsb                           ; get first byte
gtp_retry:
                mov     si, bx                  ; begin token string
                jcxz    gtp_error
                repne   scasb                   ; find first occurrence
                jne     gtp_error               ; not found
                dec     di                      ; fix overshoot
                push    cx                      ; save current position
                mov     cx, token_strlen        ;
                repe    cmpsb                   ;
                pop     cx                      ; 'current position'
                jne     gtp_retry

;*
;* Token found, DI now points to char after 'token_str' in config line
;*
                push    di
                mov     ax, es
                mov     ds, ax
                mov     si, di
                les     di, target_ptr
                                                ; ds:si -> string
                                                ; es:di -> target
                mov     ax, es
                or      ax, di
                .if     <nz>
                        ;*
                        ;* ptr != NULL
                        ;*

@@:                     lodsb
                        .if     <nonzero al> and
                        .if     <al ne ' '>

;* call   toupper
                                stosb
                                jmp     @B
                        .endif                  ; end of string test

                        xor     al, al          ; null
                        stosb                   ; terminate target

                .endif                          ; NULL ptr test

                pop     di

;*
;* Calculate ptr into original
;*
                lea     bx, config_line         ; start of data area
                sub     di, bx                  ; calc offset
                les     si, source_ptr          ; get orig
                add     si, di                  ; adjust orig
                mov     ss:[bx-16], si          ; replace SI for POPA
                clc                             ; explicit, no error
                jmp     short gtp_exit          ; ES:SI -> req'd char

;*
;* Get length of given null terminated string (in CX).
;*
gtp_getlen:     mov     cx, 0FFH                ; max length
                xor     al, al                  ; to search for
                repne   scasb                   ; scans ES:DI
                jne     gtp_gexit               ; too long/not found
                not     cl
                dec     cl                      ; CX has string length
                xor     ch, ch                  ; Note: sets ZR
gtp_gexit:      retn                            ; ZR set if CX valid

gtp_error:      stc
gtp_exit:       popa
                pop     ds

FREEVAR token_strlen
FREEVAR config_line

ENDPROC         get_token_ptr


;/***************************************************************************
;*
;* FUNCTION NAME = toupper
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

toupper         proc    near
                cmp     al, 'a'
                jb      @F
                cmp     al, 'z'
                ja      @F
                sub     al, 'a'-'A'
@@:             ret
toupper         endp


;/***************************************************************************
;*
;* FUNCTION NAME = extract_parm
;*
;* DESCRIPTION   = Extract parameter from config line
;*
;*
;* INPUT         = es:si -> src, ds:di -> dest, cx dest max len
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = nc if ok
;*
;* RETURN-ERROR  = cy if len exceeded
;*
;**************************************************************************/

extract_parm    proc    near

xtp0:           mov     al, es:[si]
                or      al, al
                jz      xtp1                    ; jif eois
                cmp     al, ' '
                jz      xtp1                    ; jif eow
                cmp     al, 'a'
                jl      xtpu
                cmp     al, 'z'
                jg      xtpu
                and     al, 5fh                 ; convert to upper

xtpu:           mov     [di], al
                inc     si
                inc     di
                loop    xtp0                    ; thru all dest

xtp1:           jcxz    xtp2                    ; dest end reached
                mov     byte ptr [di], 0        ; terminate dest string
                clc
                jmp     short xtpx

xtp2:           stc

xtpx:           ret

extract_parm    endp


;/***************************************************************************
;*
;* FUNCTION NAME = getnum
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

getnum          proc

                ;*
                ;* get 1st char
                ;*
                mov     bl, es:[si]
                inc     si
                xor     bh, bh                  ; ucbw

                .if     <nonzero bl>

                        xor     ax, ax          ; init digit accumulator
                        mov     cx, 1           ; init digit count

                        .while  <bl be '9'> and
                        .while  <bl ae '0'>

                                sub     bl, '0'
                                imul    ax, 10
                                add     ax, bx

                                mov     bl, es:[si]
                                inc     si
                                inc     cx

                        .endwhile               ; valid digit test

                        ;*
                        ;* go back to non digit char
                        ;*
                        dec     si
                        dec     cx

                        ;*
                        ;* test accumulation count
                        ;*
                        .if     <zero cx>
                                stc             ; no digits found
                        .else
                                clc             ; digits found
                        .endif

                .else                           ; no chars found
                        stc
                .endif

                ret

getnum          endp


;/***************************************************************************
;*
;* FUNCTION NAME = itos
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

PROCEDURE       itos    near

PARAMETER       str_ptr         word

BEGINPROC
                pusha
                mov     si, str_ptr
                push    ax
                call    itoa
                pop     ax

                ;*
                ;* remove leading zeros
                ;*
                .if     <ax b 100>
                        mov     byte ptr [si], ' '
                        inc     si
                        .if     <ax b 10>
                                mov     byte ptr [si], ' '
                        .endif
                .endif

                popa

ENDPROC         itos


;/***************************************************************************
;*
;* FUNCTION NAME = itoa
;*
;* DESCRIPTION   =
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

itoa            proc    near

                mov     cx, 10
                xor     dx, dx
                div     cx

                .if     <ax ne 0>
                        push    dx
                        call    itoa
                        pop     dx
                .endif

                add     dl, '0'
                mov     [si], dl
                inc     si

                ret

itoa            endp

;*
;* end
;*
