📄 setargv.asm
字号:
NAME SETARGV
PAGE 60,132
;[]------------------------------------------------------------[]
;| SETARGV.ASM -- Parse Command Line |
;| |
;| Turbo-C Run Time Library version 2.0 |
;| |
;| Copyright (c) 1987,1988 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__
ifdef WILD
ExtProc@ sbrk, __CDECL__
endif
SUBTTL Parse Command Line
PAGE
;/* */
;/*-----------------------------------------------------*/
;/* */
;/* Parse Command Line */
;/* ------------------ */
;/* */
;/*-----------------------------------------------------*/
;/* */
PSPCmd equ 00080h
CSeg@
IF LPROG
SavedReturn dd ?
ELSE
SavedReturn dw ?
ENDIF
SavedDS dw ?
SavedBP dw ?
ifdef WILD
;------------------------------------------------------------------------------
;
; Not enough space on stack for the program name.
;
BadProgName label near
jmp abort@
endif
;==============================================================================
ifdef WILD
PubProc@ _wildargv, __CDECL__
else
PubProc@ _setargv, __CDECL__
endif
; First, save caller context and Return Address
pop word ptr SavedReturn
IF LPROG
pop word ptr SavedReturn+2
ENDIF
mov SavedDS, ds
cld
; Compute Command Line size
mov es, _psp@
mov si, PSPCmd ; ES: SI = Command Line address
xor ah, ah
lods byte ptr es:[si]
inc ax ; AX = Command Line size including \r
mov bp, es
xchg dx, si ; BP:DX = Command Line address
xchg bx, ax ; BX = Command line size
; Compute Program Name size
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
xor al, al
repnz scasb
jcxz BadProgName
xor cl, 07fh ; CX = Filename size (includes \0)
NoProgramName label near
; Reserve space for the arguments
sub sp, 2 ; To be sure nothing in SS:FFFF
mov ax, 1
ifndef WILD
add ax, bx
endif
add ax, cx
and ax, not 1
mov di, sp
sub di, ax
jb BadProgName
mov sp, di ; SS:DI = Command Line storage address
; Copy ProgName to the stack
mov ax, es
mov ds, ax
mov ax, ss
mov es, ax
ifndef WILD
push cx
endif
dec cx
rep movsb
xor al, al
stosb ; ASCIIZ string
; Process Command Line.
;==============================================================================
ifdef WILD
;==============================================================================
;
; The value of "wild_attr" is used in the "findfirst" call as the file
; attribute.
;
; The default value is 0, which will only include "regular" files.
;
; Adding 10H to this value will include directories, 04h will include system
; files, and 02h will include hidden files.
;
wild_attr equ 0 ; include only regular files
;------------------------------------------------------------------------------
ffblk struc
ff_reserved db 21 dup (?)
ff_attrib db ?
ff_ftime dw ?
ff_fdate dw ?
ff_fsize dd ?
ff_name db 14 dup (?)
ffblk ends
wild_init_space equ 128 ; initial buffer allocation
wild_more_space equ 256 ; buffer size increment
;------------------------------------------------------------------------------
wild_buff_addr equ [bp]
wild_buff_size equ [bp+4]
wild_buff_max equ [bp+6]
wild_arg_src equ [bp+8]
wild_arg_dst equ [bp+10]
wild_argument equ [bp+12]
wild_destin equ [bp+16]
wild_path_len equ [bp+20]
wild_argc equ [bp+22]
wild_DTA_save equ [bp+24]
wild_ffblk equ [bp+28]
wild_frame_size equ 28 + TYPE ffblk
;------------------------------------------------------------------------------
mov cx, bp ; save segment of command line
dec bx ; don't need trailing \0
sub sp, wild_frame_size
mov bp, sp ; bp points at local variables
push dx ; save cmd line addr
push cx ; save cmd line seg
push bx ; save cmd line size
mov ax, wild_init_space
mov wild_buff_size, ax ; save initial size
ifndef __HUGE__
mov ds, savedDS
endif
push ax
call sbrk@
pop cx ; toss parameter
pop cx ; restore cmd line size
pop ds ; restore cmd line seg
pop si ; restore cmd line addr
mov wild_buff_addr, ax ; save offset
if LDATA
mov wild_buff_addr+2, dx ; save segment
and ax, dx
else
mov wild_buff_addr+2, ss ; seg = SS
endif
cmp ax, -1
je NoSbrkSpace ; abort if not enough space
add ax, wild_buff_size
mov wild_buff_max, ax ; save max offset
mov ah, 2fh
int 21h ; get current DTA
mov wild_DTA_save, bx
mov wild_DTA_save+2, es
push ds
push ss ; fflbk is on stack
pop ds
lea dx, wild_ffblk
mov ah, 1ah
int 21h ; switch DTA to ffblk
pop ds
les di, dword ptr wild_buff_addr
xor dx, dx ; dx = # of arguments
;
; Start new argument.
;
NewArg: mov wild_arg_dst, di
xor bh, bh ; bh = wildcard flag
;
; Skip leading whitespace.
;
ArgCopy: mov wild_arg_src, si ; save address of argument
call GetChar
jc ArgCopyDone ; jump if no more characters
jz ArgCopyLoop
cmp al, ' '
je ArgCopy ; skip whitespace
cmp al, 9
je ArgCopy
cmp al, 13
je ArgCopy
cmp al, '"'
je ArgQuote ; jump if quoted string
;
; Loop to copy unquoted argument.
;
ArgCopyLoop: call ArgPushChar ; store character in destination
call GetChar
jc ArgComplete ; jump if end of line
jz ArgCopyLoop ; jump if \"
cmp al, ' '
je ArgComplete ; whitespace terminates
cmp al, 9
je ArgComplete
cmp al, 13
je ArgComplete ; whitespace terminates
cmp al, '"'
jne ArgCopyLoop
ArgComplete: call ProcessArg ; copy or expand argument
jmp SHORT NewArg
NoSbrkSpace: jmp abort@ ; error jump
;
; Here if quoted argument.
;
ArgQuote: call GetChar
jc QuoteDone
jz QuoteNext
cmp al, '"' ; terminating quote ?
je QuoteDone
QuoteNext: call ArgPushChar ; store character in destination
jmp SHORT ArgQuote
;
; End of a quoted argument. Push terminating null, do not expand.
;
QuoteDone: xor al, al
call ArgPushChar ; push terminating null
inc dx ; bump arg count
jmp SHORT NewArg ; go get more
;------------------------------------------------------------------------------
;
; Here when done expanding command line. Go build the argv array.
;
ArgCopyDone: mov ax, di ; ax = unused space
sub ax, wild_buff_max
jz ArgNoWaste ; skip if all used
push dx
push di
ifndef __HUGE__
mov ds, savedDS
endif
push ax
call sbrk@ ; release unused memory
pop cx ; toss parameter
pop di
pop dx
ArgNoWaste: lds si, dword ptr wild_buff_addr
mov cx, di
sub cx, si ; cx = number of bytes in expanded line
inc dx ; count program name
jmp BuildArgv
;------------------------------------------------------------------------------
;
; Routine to retrieve the next character from the command line.
; Sets CF when end of line reached.
; Sets ZF when \ character found (i.e. \")
;
; bh.bit0 set if wildcard chars found (* or ?)
; bh.bit1 set if \ character found (\")
;
GetChar proc near
jcxz GchEnd ; jump if no more
lodsb
dec cx
cmp al, '\' ; escape ?
je GchEsc
cmp al, '?'
je GchWild
cmp al, '*'
je GchWild
GchRet: or ah, 1 ; clear CF and ZF
ret
GchWild: test bh, bh
jnz GchRet ; give up if \" has been found
or bh, 1
ret
GchEsc: jcxz GchRet ; check for \ at end of line
cmp byte ptr [si],'"'
jne GchRet ; only \" is special
lodsb
dec cx
mov bh, 2 ; set \ flag
xor ah, ah ; clear CF, set ZF
ret
GchEnd: stc
ret
GetChar endp
;------------------------------------------------------------------------------
;
; Routine to expand a wildcard parameter.
;
; DS:SI = argument address
; ES:DI = destination
; Returns:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -