home *** CD-ROM | disk | FTP | other *** search
- ;----------------------------------------------------------------
- ; This is a module in the ASMLIB library.
- ;
- ; This is the token processing module. It is responsible for
- ; all the token processing and contains the following code
- ;
- ; 1) DEFDEL Define Token delimeters
- ; 2) GETTOK Get a token from a string
- ; 3) TABSRC Search a table for a token
- ;
- ; Written R.C.H. 22/10/83
- ; Last Update R.C.H. 01/11/83
- ;----------------------------------------------------------------
- ;
- name 'token'
- extrn cmpstr,delstr
- public gettok,defdel,tabsrc
- maclib z80
- ;
- ;
- defdel:
- sded delims ; Save the address of the delimeters
- push b
- ldax d ; get size of the string
- ora a ; return a zero if size = 0
- pop b
- ret
- ;
- ; This is a major routine which must use the delimeter string to define
- ; where a token will end. If no delimeter then the token ends on a string
- ; boundary. If no delimeters then return a carry set to indicate an error.
- ; On entry DE -> string to extract a token from
- ; HL -> Destination for the token
- ; B -> maximum allowable length for a token.
- ;
- ; On exit carry set means error.
- ; if destination count too small then carry returned
- ; When a token is returned the delimeter that caused the return is
- ; appended to the end of the string. This is always done.
- ;
- ; This module has been written with the aid of a pseudo code sketch.
- ;
- ; start:
- ; get size of input string
- ; if zero then return
- ; get length of delimeter string
- ; if zero then return
- ; main loop:
- ; get a character
- ; load into destination string
- ; check if a delimeter
- ; if so thgen return no zer or carry
- ; check if destination full
- ; if so then return a carry
- ; check if source empty.
- ; if so then return a zero
- ; goto main loop.
- ;
- ;
- gettok:
- ldax d
- ora a ; is source string zero length ?
- rz ; exit with zero for end of job
- shld dst$adr ; save destination string address
- sded src$adr ; save source string address
- mov c,a ; save the original length
- sbcd siz$str ; save original size setups
- ;
- main1: ; main loop. DE -> source, HL -> dest, B = dest size, C = source size
- inx d ; point ot a character in the source
- inx h ; point to next character in the dest
- ldax d ; get a character
- mov m,a ; save it
- dcr c ; decrement the source size
- dcr b ; decrement the dest size
- ; Check if the character was a delimeter.
- call chk$delim ; check. return zero true if so
- jrz delim$end ; delimetered end return
- ; Check if the source is empty. This is a valid return
- mov a,c
- ora a
- jrz delim$end ; this is a delimetered end, cr did it
- ; check if the dest is full
- mov a,b
- ora a
- jrz end$dest ; set carry to indicate the error
- ; All else means that we get another character
- jmp main1 ; keep on going
- ;
- ; Here and the destination went full prematurely so we signal the error
- ; and exit without saving any string lengths etc.
- ;
- end$dest: ; end of destination buffer, signal an error
- stc ; set the carry flag
- lhld dst$adr
- lded src$adr
- ret
- ;
- ; Here and the string was properly delimetered by either the source string end
- ; or there was a match with a token delimeter character. When this happens we
- ; must change the string sizes in both the source and dest strings
- ;
- delim$end:
- lded siz$str ; get original sizes into DE
- mov a,e ; get original source string size
- sub c ; take decremented size
- lhld dst$adr ; get start address of dest string
- mov m,a ; save size of the destination string
- ;
- mov b,a ; save a copy for the delete
- mvi c,1 ; start at character 1
- lded src$adr ; start of source string
- call delstr ; delete the substring
- ret
- ;
- ; This routine returns a zero if the character in A matches a delimeter
- ; character in the delimeter string.
- ;
- chk$delim:
- push h ; save
- push b ; save maximum string length bytes
- lhld delims ; get delimeter string address
- mov b,m ; get string size
- chk$loop: ; loop here checking bytes
- inx h ; point to next delimeter
- cmp m
- jrz chk$match ; matches a delimeter
- djnz chk$loop ; loop on
- mvi a,0ffh ; ensure zero flag off
- ;
- ; If the following is jumped then the zero flag is not turned off
- ; and we return saying that there was a match therefore
- ;
- ora a
- chk$match: ; jump here if a match, zero maintained
- pop b
- pop h ; restore all
- ret
- ;
- ;----------------------------------------------------------------
- ; This routine must search a table of strings for a match with the
- ; input string. If it matches then a return is done with the carry
- ; off , zero off and A= index into the table where the match happened.
- ; If there was no match then return with a zero in a and a zero flag.
- ;
- ; No entry DE -> string
- ; HL -> table end of table has a string size of 00.
- ;
- ; Note that the routine assumes the table is in alpha order.
- ; This routine uses the external referenced compare routine
- ;
- ;----------------------------------------------------------------
- ;
- tabsrc:
- ldax d ; get source string length
- ora a
- rz ; return if a zero
- mvi c,01 ; count strings checked.
- shld dst$adr ; save table address
- sded src$adr ; save string address
- ; Now we can check the strings.
- ; DE -> the source string
- ; HL -> table string
- tab$loop:
- push b
- call cmpstr ; compare them
- pop b
- mov a,c
- rz ; exit with a = number checked if =
- ; If no carry then the table string > source string so error exit
- jrc err$exit
- ; Else we must index to the next string in the table
- lhld dst$adr ; get start of the string
- mov e,m
- mvi d,00 ; make an index
- dad d ; point to next string
- inx h ; make up for counter byte
- mov a,m ; is table length = 0
- ora a
- rz
- shld dst$adr ; save it
- lded src$adr ; get address of string again
- inr c
- jr tab$loop
- ;
- ;
- err$exit:
- xra a ; indicate a not found string
- stc
- ret
- ;
- dseg
- delims: db 00,00 ; initialize to zero for checking
- src$adr db 00,00 ; source string address
- dst$adr db 00,00 ; destination string address
- siz$str db 00,00 ; original string setup sizes
- end
-
-
-