231 lines
4.9 KiB
NASM
231 lines
4.9 KiB
NASM
|
NAME setargv
|
||
|
PAGE 60,132
|
||
|
;[]------------------------------------------------------------[]
|
||
|
;| SETARGV.ASM -- Parse Command Line |
|
||
|
;| |
|
||
|
;| Turbo-C Run Time Library version 1.0 |
|
||
|
;| |
|
||
|
;| Copyright (c) 1987 by Borland International Inc. |
|
||
|
;| All Rights Reserved. |
|
||
|
;[]------------------------------------------------------------[]
|
||
|
|
||
|
INCLUDE RULES.ASI
|
||
|
|
||
|
; Segment and Group declarations
|
||
|
|
||
|
Header@
|
||
|
|
||
|
; External references
|
||
|
|
||
|
ExtSym@ __argc, WORD, __CDECL__
|
||
|
dPtrExt@ __argv, __CDECL__
|
||
|
ExtSym@ _psp, WORD, __CDECL__
|
||
|
ExtSym@ _envseg, WORD, __CDECL__
|
||
|
ExtSym@ _envLng, WORD, __CDECL__
|
||
|
ExtSym@ _osmajor, BYTE, __CDECL__
|
||
|
ExtProc@ abort, __CDECL__
|
||
|
|
||
|
SUBTTL Parse Command Line
|
||
|
PAGE
|
||
|
;/* */
|
||
|
;/*-----------------------------------------------------*/
|
||
|
;/* */
|
||
|
;/* Parse Command Line */
|
||
|
;/* ------------------ */
|
||
|
;/* */
|
||
|
;/*-----------------------------------------------------*/
|
||
|
;/* */
|
||
|
PSPCmd equ 00080h
|
||
|
|
||
|
|
||
|
CSeg@
|
||
|
|
||
|
IF LPROG
|
||
|
SavedReturn dd ?
|
||
|
ELSE
|
||
|
SavedReturn dw ?
|
||
|
ENDIF
|
||
|
SavedDS dw ?
|
||
|
SavedBP dw ?
|
||
|
|
||
|
PubProc@ _setargv, __CDECL__
|
||
|
|
||
|
; First, save caller context and Return Address
|
||
|
|
||
|
pop word ptr SavedReturn
|
||
|
IF LPROG
|
||
|
pop word ptr SavedReturn+2
|
||
|
ENDIF
|
||
|
mov SavedDS, ds
|
||
|
|
||
|
; Then, Process command line
|
||
|
|
||
|
cld
|
||
|
mov es, _psp@
|
||
|
mov si, PSPCmd ; ES: SI = Command Line address
|
||
|
xor ax, ax
|
||
|
mov bx, ax
|
||
|
mov dx, ax ; AX = BX = CX = DX = 0
|
||
|
mov cx, ax ; AX = BX = CX = DX = 0
|
||
|
lods byte ptr es:[si]
|
||
|
mov di, si
|
||
|
xchg ax, bx
|
||
|
mov es:[di+bx], al ; Append a \0 at the end
|
||
|
inc bx
|
||
|
xchg bx, cx ; CX = Command Line size including \0
|
||
|
Processing label near
|
||
|
call NextChar
|
||
|
ja NotQuote ; Not a quote and there are more
|
||
|
InString label near
|
||
|
jb GetArg0Lgth ; Command line is empty now
|
||
|
call NextChar
|
||
|
ja InString ; Not a quote and there are more
|
||
|
NotQuote label near
|
||
|
cmp al, ' '
|
||
|
je EndArgument ; Space is an argument separator
|
||
|
cmp al, 9
|
||
|
jne Processing ; TAB is an argument separator
|
||
|
EndArgument label near
|
||
|
xor al, al ; Space and TAB are argument separators
|
||
|
jmp short Processing
|
||
|
|
||
|
; Character test function used in SetArgs
|
||
|
; On entry AL holds the previous character
|
||
|
; On exit AL holds the next character
|
||
|
; ZF on if the next character is quote (") and AL = 0
|
||
|
; CF on if end of command line and AL = 0
|
||
|
|
||
|
NextChar PROC NEAR
|
||
|
or ax, ax
|
||
|
jz NextChar0
|
||
|
inc dx ; DX = Actual length of CmdLine
|
||
|
stosb
|
||
|
or al, al
|
||
|
jnz NextChar0
|
||
|
inc bx ; BX = Number of parameters
|
||
|
NextChar0 label near
|
||
|
xchg ah, al
|
||
|
xor al, al
|
||
|
stc
|
||
|
jcxz NextChar2 ; End of command line --> CF ON
|
||
|
lods byte ptr es:[si]
|
||
|
dec cx
|
||
|
sub al, '"'
|
||
|
jz NextChar2 ; Quote found --> AL = 0 and ZF ON
|
||
|
add al, '"'
|
||
|
cmp al,'\'
|
||
|
jne NextChar1 ; It is not a \
|
||
|
cmp byte ptr es:[si], '"'
|
||
|
jne NextChar1 ; Only " is transparent after \
|
||
|
lods byte ptr es:[si]
|
||
|
dec cx
|
||
|
NextChar1 label near
|
||
|
or si, si ; Be sure both CF & ZF are OFF
|
||
|
NextChar2 label near
|
||
|
ret
|
||
|
NextChar ENDP
|
||
|
|
||
|
; Invalid program name
|
||
|
|
||
|
BadProgName label near
|
||
|
jmp abort@
|
||
|
|
||
|
; Now, Compute Argv[0] length
|
||
|
|
||
|
GetArg0Lgth label near
|
||
|
mov bp, es ; BP = Program Segment Prefix address
|
||
|
mov si, _envLng@
|
||
|
add si, 2 ; SI = Program name offset
|
||
|
mov cx, 1 ; CX = Filename size (includes \0)
|
||
|
cmp _osmajor@, 3
|
||
|
jb NoProgramName
|
||
|
mov es, _envseg@
|
||
|
mov di, si ; SI = argv[0] address
|
||
|
mov cl, 07fh
|
||
|
repnz scasb
|
||
|
jcxz BadProgName
|
||
|
xor cl, 07fh ; CX = Filename size (includes \0)
|
||
|
NoProgramName label near
|
||
|
|
||
|
; Now, reserve space for the arguments
|
||
|
|
||
|
ReserveSpace label near
|
||
|
inc bx ; argv[0] = PgmName
|
||
|
mov __argc@, bx
|
||
|
inc bx ; argv ends with NULL
|
||
|
mov ax, cx ; Size = PgmNameLgth +
|
||
|
add ax, dx ; CmdLineLgth +
|
||
|
add bx, bx ; argc * 2 (LDATA = 0)
|
||
|
IF LDATA
|
||
|
add bx, bx ; argc * 4 (LDATA = 1)
|
||
|
ENDIF
|
||
|
add ax, 1
|
||
|
and ax, not 1 ; Keep stack word aligned
|
||
|
add bx, ax
|
||
|
mov di, sp
|
||
|
sub di, ax ; SS:DI = DestAddr for PgmName
|
||
|
sub sp, bx ; SS:SP = &argv[0]
|
||
|
xchg bx, bp ; BX = Program Segment Prefix address
|
||
|
mov bp, sp ; BP = &argv[0]
|
||
|
mov word ptr __argv@, sp
|
||
|
IF LDATA
|
||
|
mov word ptr __argv@+2, ss
|
||
|
ENDIF
|
||
|
mov ax, ss
|
||
|
mov es, ax ; ES:DI = Argument's area
|
||
|
|
||
|
; Copy program name
|
||
|
|
||
|
CopyArg0 label near
|
||
|
mov [bp], di ; Set argv[n]
|
||
|
IF LDATA
|
||
|
mov [bp+2], es
|
||
|
add bp, 4
|
||
|
ELSE
|
||
|
add bp, 2
|
||
|
ENDIF
|
||
|
mov ds, _envseg@
|
||
|
dec cx
|
||
|
rep movsb
|
||
|
xor al, al
|
||
|
stosb
|
||
|
|
||
|
; Copy the command line
|
||
|
|
||
|
mov ds, bx
|
||
|
xchg cx, dx ; CX = Command Line size
|
||
|
mov si, PSPCmd + 1 ; DS: SI = Command Line address
|
||
|
CopyArgs label near
|
||
|
jcxz SetLastArg
|
||
|
mov [bp], di ; Set argv[n]
|
||
|
IF LDATA
|
||
|
mov [bp+2], es
|
||
|
add bp, 4
|
||
|
ELSE
|
||
|
add bp, 2
|
||
|
ENDIF
|
||
|
CopyArg label near
|
||
|
lodsb
|
||
|
or al, al
|
||
|
stosb
|
||
|
loopnz CopyArg
|
||
|
jz CopyArgs
|
||
|
SetLastArg label near
|
||
|
xor ax, ax
|
||
|
mov [bp], ax
|
||
|
IF LDATA
|
||
|
mov [bp+2], ax
|
||
|
ENDIF
|
||
|
|
||
|
; Restore caller context and exit
|
||
|
|
||
|
mov ds, SavedDS
|
||
|
IF LPROG
|
||
|
jmp dword ptr SavedReturn
|
||
|
ELSE
|
||
|
jmp word ptr SavedReturn
|
||
|
ENDIF
|
||
|
EndProc@ _setargv, __CDECL__
|
||
|
CSegEnd@
|
||
|
END
|