home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
xbase
/
library
/
clipper
/
keyboard
/
caps
/
fcap.asm
next >
Wrap
Assembly Source File
|
1986-03-12
|
8KB
|
201 lines
;-------------------------------:
; Program File.: FCAP.ASM :
; Author.......: Dennis L. Dias :
; Source ID....: NAN449 :
; Date.........: 12/14/85 :
;-------------------------------:
;
;-------------------------------------------------------------------:
;This assembly language routine is called by Clipper to convert :
; the first letter of each word of the input string to caps. The :
; special words listed as "special" below will remain lower case :
; unless they appear as the first or last word or if they are :
; followed by a non-space character. The input string must be passed:
; as lower case. :
; The apostrophe (') is considered a character. :
;-------------------------------------------------------------------:
;
public fcap ;Public procedure
;
_prog segment byte ;Clipper segment
assume cs:_prog,ds:_prog,es:nothing,ss:nothing
;
;----------------:
;Local data area :
;----------------:
;
;Special words are grouped according to length. Each group is
; preceeded by the length plus one space, and the number of words of
; that length. This greatly reduces the number of comparisons
; required to search the entire list. These numbers MUST be changed
; when adding or removing words from the list.
;
special db 4,4,"and the for but "
db 3,9,"to or by an in of on if at "
db 2,1,"a ",0 ;Special words are terminated with null
;
;List of characters to be considered "in-word" characters
;
char db "0123456789abcdefghijklmnopqrstuvwxyz'"
;
;------------------------------------------------------:
;Primary routine..far procedure as required by Clipper :
;------------------------------------------------------:
;
fcap proc far
;
push bp ;Required by Clipper
mov bp,sp ;To address variable at SP + 6
push ds ;Must save seg regs
push es
cld ;Forward direction flag
;
lds si,dword ptr[bp+6] ;Point to input string with DS:SI
push cs
pop es ;Address local data via ES register
;
lea di,char ;ES:DI points to in-word characters
mov cx,37 ;Length of in-word characters
;
;Capitalize the first word no matter what it is
;
fc1: lodsb ;Fetch char
or al,al ;Check for null terminator
jz fc_ret ;Quit if null..no characters at all
;
call fl_scan ;Test for in-word character
jnz fc1 ;Scan off word separators
mov bx,si
dec bx ;DS:BX points to first character
call fl_cap ;Cap first letter
;
;Return here for each new word
;
fc2: mov bx,si
dec bx ;DS:BX points to first character
;
fc3: lodsb ;Fetch character
or al,al ;Check for null terminator
jz fc5 ;Cap last word
;
call fl_scan ;Test for in-word character
jz fc3 ;Scan past in-word characters
;
fc4: mov dx,si
sub dx,bx ;DX has size of word plus 1
cmp dl,4 ;Special words are 3 chars
ja fc5 ; plus 1 space max
;
call fl_com ;Test for special word
jc fc6 ;Found..don't cap
;
fc5: call fl_cap ;Cap first letter
;
fc6: dec si ;Point to end of prev word + 1
lea di,char ;Point to in-word characters
mov cx,37 ;Length of in-word characters
;
fc7: lodsb ;Fetch char
or al,al ;Check for null terminator
jz fc_ret ;Quit if null
;
call fl_scan
jnz fc7 ;Scan off word separators
jmp fc2 ;Go process next word
;
;Done
;
fc_ret: pop es ;Restore registers for Clipper
pop ds
pop bp
ret ;Far return to Clipper
;
fcap endp
;
;------------------:
;Local subroutines :
;------------------:
;
;The following procedure tests the character in AL as being in-word
; or not. The zero flag returns set if the character is in-word.
;
fl_scan proc near
;
push di ;Save pointer to in-word characters
push cx ;Save length of in-word characters
repne scasb ;Look for match
pop cx ;Restore saved values and return
pop di ; result in Zero flag
ret ;Near return
;
fl_scan endp
;
;Convert lower case to upper case..DS:BX points to the character
;
fl_cap proc near
;
cmp byte ptr[bx],"a"
jb fl_cap_ret ;Less than "a" not lower
cmp byte ptr[bx],"z"
ja fl_cap_ret ;Above "z" not lower
sub byte ptr[bx],20h ;Convert to upper case
;
fl_cap_ret: ret ;Near return
;
fl_cap endp
;
;Look for special words..return carry flag set if found..on entry
;DS:BX points to first character of the word to test. Begin by
;exchanging the contents of ES with DS to facilitate the use of the
;string instructions. AX, CX, DX, and DI destroyed.
;
fl_com proc near
;
push si ;Save current pointer
push ds
pop es ;Clipper segment to ES
push cs
pop ds ;Local segment to DS
mov di,bx ;ES:DI points to current word
lea si,special ;DS:SI points to local list of words
;
fl_c1: lodsb ;Fetch word size
or al,al ;Check for null terminator
jz fl_clc ;Exit routine..special word not found
;
mov cl,al ;Size of next group of words to count reg
xor ch,ch ;Zero high byte
lodsb ;Fetch word count
mov dh,al ;To DH for outer loop
mov ax,cx ;Save count in AX
;
fl_c2: push di ;Save pointer to test word
mov cx,ax ;Word size to counter
repe cmpsb ;Compare bytes
je fl_stc ;Jump if special word found
add si,cx ;Point to next word or next group
pop di ;Recover pointer to test word
dec dh ;Reduce outer loop counter
jnz fl_c2 ;Anoter word..same length
jmp fl_c1 ;Go for next group of words
;
fl_clc: clc ;Clear carry..special word not found
;
fl_com_ret: pop si ;Restore registers and return
push es
pop ds ;Clipper segment to DS
push cs
pop es ;Local segment to ES
ret ;Near return
;
;Special word found..return result in carry flag
;
fl_stc: pop di ;Clear stack
stc ;Set carry flag
jmp fl_com_ret ;Restore and return
;
fl_com endp
_prog ends
end