Category : Word Processors
Archive   : PREFIX.ZIP
Filename : PREFIX.ASM

 
Output of file : PREFIX.ASM contained in archive : PREFIX.ZIP

PAGE 55,130
; PREFIX.ASM
; This program accepts a quoted string from the command line and prefixes
; it to each line received from std in, writing it to std out.
; DOS I/O redirection is used to modify files. Input line length is
; limited to 255 chars, prefix to 80 chars. Output line length is limited
; to 335 ( 255 + 80 ). These limits may be altered by changing the
; equates below.
;

pfx_len equ 050h ; prefix buffer area
ibuf_len equ 0100h ; input buffer area
obuf_len equ 0150h ; output buffer area
stk_len equ 0100h ; program stack area
total_buflen = pfx_len + ibuf_len + obuf_len + stk_len


codeseg segment
assume cs:codeseg, ds:codeseg

org 0100h

prefix proc far
start: jmp init

; ---------------------------------
msg1 db 13, 10, 'Usage is: PREFIX ', 13, 10, '$'
msg2 db 13, 10, 'Unable to allocate memory - aborting.'
db 13, 10, '$'
; ---------------------------------

init: mov bx,offset pgm_end
add bx,0Fh
mov cl,4
shr bx,cl
mov ah,04Ah ; allocate memory explicitly
int 021h
mov dx,offset msg2 ; set up error message
jc err_exit ; quit if cf=1
xor ax,ax ; init buffers and stk
mov di,offset last_line ; to all 0's
mov cx,total_buflen
shr cx,1
cld
rep stosw
mov sp,offset pgm_end

mov si,81h ; point si to command line parms
call get_prefix ; get the quoted suffix string
mov dx,offset msg1 ; set up other error msg
cmp al,5 ; success code
jne err_exit ; unsuccessful - quit with err msg
call get_prefix ; This checks for extra stuff on
mov dx,offset msg1
cmp al,3 ; the command line, and quits with
jne err_exit ; error msg if found.

main: call get_line ; input a line from std in
jc quit ; quit on carry set (eof or error)
call set_prefix ; prefix it
call out_put ; output it to std out
jc quit ; quit on error.
jmp main ; repeat until eof(input)

err_exit: mov di,dx
mov cx,0FFh
mov al,024h
cld
repnz scasb ; this was to get len of message
dec di
mov cx,di
sub cx,dx ; some arithmetic
mov bx,2 ; handle for std error
mov ah,040h ; output msg to std error
int 021h ; (error msg will go to con)
mov al,1 ; exit status = 1
quit: mov ah,04Ch
int 021h ; terminate process.

prefix endp

; ----------------------------------------------------------------------------
; SUBROUTINE get_prefix
; get the quoted prefix into the holding area
;

get_prefix proc near
call rem_space ; eat up blanks on cmd line
mov di,si ; save si in di
cmp byte ptr [si],0Dh ; see if we have eoln
jne Q1 ; no, continue
mov al,3 ; else return eoln code.
ret

Q1: mov dl,022h ; double quote
cmp [si],dl
je P1 ; ok, continue
mov dl,027h ; single quote
cmp [si],dl
je P1 ; still ok, continue
mov al,4 ; no, return non-quote code.
ret

P1: inc si ; now get quoted string into vacant
mov di,offset last_line ; prefix buffer area

Q2: lodsb ; get [si] into al
cmp al,dl ; check for matching quote, still in
je Q3 ; dl. If found, we're done.
cmp al,0Dh ; check for eoln
je P2 ; if found here, error
stosb ; OK - store al to es:[di]
cmp di,offset in_buffer
je P2 ; too many chars, exit with error
jmp Q2 ; repeat until done or error.
Q3: mov al,5 ; success.

P3: mov byte ptr [di],0 ; null terminate the string
mov di,offset last_line ; reset di
ret

P2: mov al,6 ; error (non-success) code
jmp P3

get_prefix endp

; --------------------------------------------------------------------------
; SUBROUTINE get_line
; inputs a string (line) from std in

get_line proc near
mov si,offset in_buffer ; point si to input buffer

G1: mov dx,si ; point dx to input buffer
mov cx,1 ; set char count to 1
mov bx,0 ; select handle for input
mov ah,03Fh ; DOS input from std in
int 021h

jc getline_ret ; error, code in ax
stc
mov cx,ax ; ax = chars read
jcxz getline_ret ; return if no chars read
cmp byte ptr [si],0Ah ; eoln, return
je getline_ret
cmp byte ptr [si],01Ah ; check for eof
stc
jz getline_ret ; eof, ret w/carry set
inc si ; inc si
cmp si,offset out_buffer ; check for buffer overrun
jb G1 ; OK, repeat
stc ; else, ret w/carry set

getline_ret: ret

get_line endp

; -------------------------------------------------------------------------
; SUBROUTINE set_prefix
; prefixes the line that was input

set_prefix proc near
mov di,offset out_buffer ; point di to output buffer

; first move the prefix into the output buffer:

mov si,offset last_line ; restore prefix ptr to si
S1:
lodsb ; [si] into al
cmp al,0 ; end of prefix (null term.)
je S2
stosb ; al to es:[di]
jmp S1 ; repeat

; now move the input line into the output buffer:

S2:
mov si,offset in_buffer ; set si to line buffer
S3:
lodsb ; [si] into al
stosb ; al to es:[di]
cmp al,0Ah ; check for eoln
jne S3 ; repeat
ret ; done - return
set_prefix endp

; -------------------------------------------------------------------------
; SUBROUTINE out_put
; outputs the string (line) to std out

out_put proc near

mov si,offset out_buffer ; point si to output buffer
mov dx,si ; put si in dx
xor cx,cx ; start cx at 0
O1:
inc cx ; pre-increment for char count
cmp cx,obuf_len ; check for buffer overrun
stc
jge output_ret ; prefix + line too long, exit
lodsb ; [si] into al
cmp al,0Ah ; see if it's eoln
jne O1 ; if not, repeat.
mov bx,1 ; set up std out
mov ah,040h ; output cx characters.
int 021h
output_ret: ret ; carry set if error.

out_put endp

; -------------------------------------------------------------------------
; SUBROUTINE rem_space
; eats up blanks

rem_space proc near
R1:
cmp byte ptr [si],020h
jne rem_space_ret
inc si
jmp R1

rem_space_ret: ret
rem_space endp

; --------------------------------------------------------------------------
; buffer allocation:

last_line label byte ; marks start of buffers area

in_buffer = last_line + pfx_len
out_buffer = in_buffer + ibuf_len
pgm_end = out_buffer + obuf_len + stk_len

codeseg ends
end start