home *** CD-ROM | disk | FTP | other *** search
- .model small
-
- .data
- PUBLIC PSPSeg
- firstScan db 1
- PSPSeg dw 0
- QUOTE EQU '"' ; if this is EQU 0, quoted strings will not be
- ; recognized as one paramter, if they contain
- ; whitespace (blanks)
- .stack 100h
-
- .code
-
- ;*******************************************************************
- ; void ScanCommands( void );
- ;
- ; Parses the command line into parameters, terminating each with
- ; a zero byte and the whole line with another zero byte.
- ; Separators for parameters are all characters <= ' '. If the QUOTE
- ; symbol is <> 0, a string enclosed in QUOTEs will be treated as one
- ; parameter, even if it contains whitespace. There may be other non-
- ; blank characters before and after the quote, which will be counted
- ; as belonging to the same parameter.
- ; Will set the firstScan variable to 0. Assumes ds=@data, preserves
- ; all registers.
- ;*******************************************************************
- ScanCommands PROC USES ax bx cx dx ds
- mov firstScan, 0 ; set flag to false
- ; set up ds:bx to point to the command line, cl with the length
- mov ds, PSPSeg
- ASSUME ds:nothing
- mov bx, 80h
- mov cl, byte ptr [bx]
- inc bx
- or cl, cl
- jz end_of_line
-
- ; The following scanning loop has two parts. First we look for
- ; a non-whitespace char as start of a parameter, then for its end.
- ; cl is tested for end of commandline conditions
- ; Throughout this loop, ch holds the QUOTE character, al the
- ; current character and ah the terminator to skip or find.
-
- mov ch, QUOTE ; load working registers
- mov ah, ' ' ; terminator is whitespace first
- ; find start of next param
- find_new_param:
- mov al, [bx] ; get next character
- cmp al, ah ; compare to current terminator (' ' here)
- ja param_start ; if it is a whitespace
- find_1:
- inc bx ; point to next character
- dec cl ; dec character counter
- jz end_of_line ; if it is zero, end of line reached
- jmp short find_new_param ; else test next char
- ; found param, seek for its end
- param_start:
- cmp al, ch ; is char the quote char?
- jne no_quote ; if yes,
- cmp al, ah ; are we currently looking for one as terminator?
- jne starting_quote ; if yes
- mov ah, ' ' ; reset terminator to blank, we found the end
- ; of a quoted string
- jmp short next_char
- starting_quote: ; else make the quote the terminator IF it is
- ; not zero!
- or ch, ch
- jz find_1 ; hey! we have a zero-terminated string here,
- ; a ready-made parameter, so seek the next
- mov ah, ch ; else look for the quote next
- jmp short next_char
- no_quote:
- cmp al, ah ; is this character a whitespace?
- ja next_char ; if yes
- cmp ah, ch ; are we looking for a quote as terminator?
- je next_char ; if not
- mov byte ptr [bx],0 ; make current character a zero char
- jmp find_1 ; and go looking for the next parameters start
-
- next_char:
- inc bx ; point to next character
- dec cl ; dec character counter
- jz end_of_line ; if it is zero, end of line reached
- mov al, [bx] ; else load the next character
- jmp short param_start; and go test it
-
- end_of_line:
- cmp bx, 100h ; are we still inside the PSP?
- jnb scan_done ; if yes
- mov byte ptr [bx], 0 ; add an additional zero byte
-
- scan_done:
- ret
- ASSUME ds:@data
-
- ScanCommands ENDP
-
- ;*******************************************************************
- ; int ParamCount( void );
- ;
- ; ParamCount returns the number of parameters on the command line
- ; in AX. Keeps all other registers unchanged.
- ; On the first run, ParamCount will parse the command line and
- ; convert each parameter to a zero-terminated string.
- ;
- ; Assumes ds is pointing to @data
- ;*******************************************************************
- ParamCount PROC PUBLIC USES si cx ds
- test firstScan, 0FFh ; flag <> 0?
- jz @F
- call ScanCommands ; if not, parse the commandline
- @@:
- ; count the zero bytes in the command tail, this now gives
- ; the number of parameters
- mov ds, PSPSeg ; point ds:si at length byte of command tail
- ASSUME ds:nothing
- mov si, 80h
- mov cl, [si]
- sub ch, ch ; cx has length of command tail
- inc si ; ds:si points to start of command tail
- sub ax, ax ; use ax to hold count
- jcxz count_done
- count_loop:
- cmp byte ptr [si], 0 ; is current char a zero byte?
- jne @F ; if yes
- inc ax ; count it
- @@:
- inc si ; next char
- dec cx
- jnz count_loop ; loop if not done
- ; slight problem here, we will not get to the zero terminating
- ; the last parameter 'cause its not included in the character count
- ; just test if the last character tested was a zero, if not, assume
- ; an additonal parameter
- dec si
- cmp byte ptr [si], 0
- je count_done
- inc ax
- count_done:
- ret
- ASSUME ds:@data
- ParamCount ENDP
-
- ;*******************************************************************
- ; char far *ParamStr( int n );
- ;
- ; ParamStr returns a far pointer to the n-th parameter on the
- ; command line in dx:ax. Count starts at 1!
- ; Uses register calling convention! n is expected in AX on entry.
- ;
- ; Assumes ds is pointing to @data. Leaves all registers except
- ; dx and ax intact.
- ;*******************************************************************
- ParamStr PROC PUBLIC USES bx cx ds
- test firstScan, 0FFh ; has command line be parsed yet?
- jz @F
- call ScanCommands ; if not, parse it now
- @@:
- mov cx, ax ; cx has index (offset from 1)
- mov ds, PSPSeg ; point ds:bx at length byte of command tail
- ASSUME ds:nothing
- mov bx, 80h
- mov al, [bx] ; use length value in al as a guard for overruns
- ; (index given > ParamCount)
- inc bx ; point ds:bx at first char
- jcxz @F ; index 0 is an error but is treated as 1 here
- dec cx ; convert index to number of zero-bytes to count
- @@:
- jcxz found_param; if cx=0, index was 1, needs no search
-
- ; now search thru the command line, counting zero bytes as proxy
- ; for a parameter
- find_loop:
- cmp byte ptr [bx], 0 ; is this the end of a param?
- jne @F ; if yes
- dec cx ; reduce count
- @@:
- inc bx ; next character
- dec al ; dec guard value
- jz overrun ; if it is now zero, we have reached the end
- ; of the command line
- jcxz found_param ; else if cx is zero, we are at the start
- ; of the requested parameter
- jmp short find_loop ; else continue search
-
- found_param:
- ; ds:bx now points at the start of a parameter. It may contain
- ; blanks at the start due to the parsing method. Skip over these.
- ; A non-blank character is guaranteed in the parameter.
- skip_blanks:
- cmp byte ptr [bx], ' ' ; is this a whitespace character?
- ja @F ; if not, done
- inc bx ; else skip it
- jmp short skip_blanks ; and test again
- @@:
- overrun: ; if overrun, bx will point to a zero-byte
- mov dx, ds ; set up result in dx:ax
- mov ax, bx
- ret
- ASSUME ds:@data
- ParamStr ENDP
-
- END