home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / CLIBSRC3.ZIP / SETARGV.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-06-10  |  27.2 KB  |  768 lines

  1. ;[]-----------------------------------------------------------------[]
  2. ;|      SETARGV.ASM -- Parse Command Line                            |
  3. ;[]-----------------------------------------------------------------[]
  4.  
  5. ;
  6. ;       C/C++ Run Time Library - Version 5.0
  7. ;       Copyright (c) 1987, 1992 by Borland International
  8. ;       All Rights Reserved.
  9.  
  10.         INCLUDE RULES.ASI
  11.  
  12. ;       Segment and Group declarations
  13.  
  14. Header@
  15.  
  16. ;       External references
  17.  
  18. ExtSym@         _C0argc,        WORD,   __CDECL__
  19. dPtrExt@        _C0argv,                __CDECL__
  20. ExtSym@         _psp,           WORD,   __CDECL__
  21. ExtSym@         _envseg,        WORD,   __CDECL__
  22. ExtSym@         _envLng,        WORD,   __CDECL__
  23. ExtSym@         _osmajor,       BYTE,   __CDECL__
  24. ExtProc@        abort,                  __CDECL__
  25.  
  26. _DATA           segment
  27. ifdef   WILD
  28.  ExtSym@        _argc,          WORD,                   __CDECL__
  29.  dPtrExt@       _argv,                                  __CDECL__
  30. else
  31.  PubSym@        _argc,          <dw     0>,             __CDECL__
  32.  dPtrPub@       _argv,          0,                      __CDECL__
  33. endif
  34. SavedReturn     dw              ?
  35. SavedDS2        dw              ?
  36. SavedReturn2    dw              ?
  37. SavedSI         dw              ?
  38. SavedDI         dw              ?
  39.                 ends
  40.  
  41. ifdef   WILD
  42. ExtProc@        sbrk,                   __CDECL__
  43. endif
  44.  
  45.         SUBTTL  Parse Command Line
  46.         PAGE
  47. ;/*                                                     */
  48. ;/*-----------------------------------------------------*/
  49. ;/*                                                     */
  50. ;/*     Parse Command Line                              */
  51. ;/*     ------------------                              */
  52. ;/*                                                     */
  53. ;/*-----------------------------------------------------*/
  54. ;/*                                                     */
  55. PSPCmd          equ     00080h
  56.  
  57. _TEXT           segment
  58.  
  59. SavedDS         dw      ?
  60.  
  61. ifdef   WILD
  62.  
  63. ;------------------------------------------------------------------------------
  64. ;
  65. ; Not enough space on stack for the program name.
  66. ;
  67. BadProgName     label   near
  68.                 jmp     abort@
  69.  
  70.                 public  __wildargv
  71. __wildargv      proc near
  72.  
  73. else
  74.  
  75. ;This is the symbol which pulls in _setargv
  76.                 public __setargv__
  77. __setargv__     equ    0
  78.  
  79. _INIT_          SEGMENT WORD PUBLIC 'INITDATA'
  80.                 db      0                       ;near call
  81.                 db      16                      ;priority 16
  82.                 dw      offset __setargv
  83.                 dw      ?
  84. _INIT_          ENDS
  85.  
  86. __setargv       proc near
  87. endif
  88.  
  89. ;==============================================================================
  90. ;       First, save caller context and Return Address
  91. ; Please be aware that this code was hacked from TC 2.0 to work with the
  92. ; new startup/exit method.  Since setargv tries to put the arguments on
  93. ; the stack it has to make an assumption about what is already on the
  94. ; stack.  Under 2.0 all that was on the stack was the return address into
  95. ; the startup code.  Under the new startup/exit method there is a return
  96. ; address (always near), a saved DS, and another near return address.
  97. ; setargv really needs to be rewritten but for now this hack is in place
  98. ; to make it work.  If you change what is on the stack in any way you will
  99. ; have to change this code!
  100.  
  101.                 pop     word ptr SavedReturn
  102.                 pop     word ptr SavedDS2
  103.                 pop     word ptr SavedReturn2
  104.                 mov     SavedDS, ds
  105.                 mov     SavedSI, si
  106.                 mov     SavedDI, di
  107.                 cld
  108.  
  109. ;       Compute Command Line size
  110.  
  111.                 mov     es, _psp@
  112.                 mov     si, PSPCmd      ; ES: SI = Command Line address
  113.                 xor     ah, ah
  114.                 lods    byte ptr es:[si]
  115.                 inc     ax              ; AX = Command Line size including \r
  116.                 mov     bp, es
  117.                 xchg    dx, si          ; BP:DX = Command Line address
  118.                 xchg    bx, ax          ; BX    = Command line size
  119.  
  120. ;       Compute Program Name size
  121.  
  122.                 mov     si, _envLng@
  123.                 inc     si
  124.                 inc     si              ; SI = Program name offset
  125.                 mov     cx, 1           ; CX = Filename size (includes \0)
  126.                 cmp     _osmajor@, 3
  127.                 jb      NoProgramName
  128.                 mov     es, _envseg@
  129.                 mov     di, si          ; SI = argv[0] address
  130.                 mov     cl, 07fh
  131.                 xor     al, al
  132.                 repnz   scasb
  133.                 jcxz    BadProgName
  134.                 xor     cl, 07fh        ; CX = Filename size (includes \0)
  135. NoProgramName   label   near
  136.  
  137. ;       Reserve space for the arguments
  138.  
  139.                 push    ax              ; To be sure nothing in SS:FFFF
  140.                 mov     ax, cx
  141. ifndef  WILD
  142.                 add     ax, bx
  143. endif
  144.                 inc     ax
  145.                 and     ax, not 1
  146.                 mov     di, sp
  147.                 sub     di, ax
  148.                 jb      BadProgName
  149.                 mov     sp, di          ; SS:DI = Command Line storage address
  150.  
  151. ;       Copy ProgName to the stack
  152.  
  153.                 push    es
  154.                 pop     ds
  155.                 push    ss
  156.                 pop     es
  157. ifndef  WILD
  158.                 push    cx
  159. endif
  160.                 dec     cx
  161.                 rep     movsb
  162.                 xor     al, al
  163.                 stosb                   ; ASCIIZ string
  164.  
  165. ;       Process Command Line.
  166.  
  167. ;==============================================================================
  168. ifdef WILD
  169. ;==============================================================================
  170.  
  171. ;
  172. ; The value of "wild_attr" is used in the "findfirst" call as the file
  173. ; attribute.
  174. ;
  175. ; The default value is 0, which will only include "regular" files.
  176. ;
  177. ; Adding 10H to this value will include directories, 04h will include system
  178. ; files, and 02h will include hidden files.
  179. ;
  180.  
  181. wild_attr       equ     0                       ; include only regular files
  182.  
  183. ;------------------------------------------------------------------------------
  184.  
  185. ffblk           struc
  186.  
  187. ff_reserved     db      21 dup (?)
  188. ff_attrib       db      ?
  189. ff_ftime        dw      ?
  190. ff_fdate        dw      ?
  191. ff_fsize        dd      ?
  192. ff_name         db      14 dup (?)
  193.  
  194. ffblk           ends
  195.  
  196. wild_init_space equ     128                     ; initial buffer allocation
  197. wild_more_space equ     256                     ; buffer size increment
  198.  
  199. ;------------------------------------------------------------------------------
  200.  
  201. wild_buff_addr  equ     [bp]
  202. wild_buff_size  equ     [bp+4]
  203. wild_buff_max   equ     [bp+6]
  204. wild_arg_src    equ     [bp+8]
  205. wild_arg_dst    equ     [bp+10]
  206.  
  207. wild_argument   equ     [bp+12]
  208. wild_destin     equ     [bp+16]
  209. wild_path_len   equ     [bp+20]
  210. wild_argc       equ     [bp+22]
  211.  
  212. wild_DTA_save   equ     [bp+24]
  213. wild_ffblk      equ     [bp+28]
  214.  
  215. wild_frame_size equ     28 + TYPE ffblk
  216.  
  217. ;------------------------------------------------------------------------------
  218.  
  219.                 mov     cx, bp                  ; save segment of command line
  220.                 dec     bx                      ; don't need trailing \0
  221.  
  222.                 sub     sp, wild_frame_size
  223.                 mov     bp, sp                  ; bp points at local variables
  224.  
  225.                 push    dx                      ; save cmd line addr
  226.                 push    cx                      ; save cmd line seg
  227.                 push    bx                      ; save cmd line size
  228.                 mov     ax, wild_init_space
  229.                 mov     wild_buff_size, ax      ; save initial size
  230. ifndef  __HUGE__
  231.                 mov     ds, SavedDS
  232. endif
  233.                 push    ax
  234.                 call    sbrk@
  235.                 pop     cx                      ; toss parameter
  236.                 pop     cx                      ; restore cmd line size
  237.                 pop     ds                      ; restore cmd line seg
  238.                 pop     si                      ; restore cmd line addr
  239.  
  240.                 mov     wild_buff_addr, ax      ; save offset
  241. if      LDATA
  242.                 mov     wild_buff_addr+2, dx    ; save segment
  243.                 and     ax, dx
  244. else
  245.                 mov     wild_buff_addr+2, ss    ; seg = SS
  246. endif
  247.                 cmp     ax, -1
  248.                 je      NoSbrkSpace             ; abort if not enough space
  249.                 add     ax, wild_buff_size
  250.                 mov     wild_buff_max, ax       ; save max offset
  251.  
  252.                 mov     ah, 2fh
  253.                 int     21h                     ; get current DTA
  254.                 mov     wild_DTA_save, bx
  255.                 mov     wild_DTA_save+2, es
  256.                 push    ds
  257.                 push    ss                      ; fflbk is on stack
  258.                 pop     ds
  259.                 lea     dx, wild_ffblk
  260.                 mov     ah, 1ah
  261.                 int     21h                     ; switch DTA to ffblk
  262.                 pop     ds
  263.  
  264.                 les     di, dword ptr wild_buff_addr
  265.                 xor     dx, dx                  ; dx = # of arguments
  266. ;
  267. ; Start new argument.
  268. ;
  269. NewArg:         mov     wild_arg_dst, di
  270.                 xor     bh, bh                  ; bh = wildcard flag
  271. ;
  272. ; Skip leading whitespace.
  273. ;
  274. ArgCopy:        mov     wild_arg_src, si        ; save address of argument
  275.                 call    GetChar
  276.                 jc      ArgCopyDone             ; jump if no more characters
  277.                 jz      ArgCopyLoop
  278.                 cmp     al, ' '
  279.                 je      ArgCopy                 ; skip whitespace
  280.                 cmp     al, 9
  281.                 je      ArgCopy
  282.                 cmp     al, 13
  283.                 je      ArgCopy
  284.                 cmp     al, '"'
  285.                 je      ArgQuote                ; jump if quoted string
  286. ;
  287. ; Loop to copy unquoted argument.
  288. ;
  289. ArgCopyLoop:    call    ArgPushChar             ; store character in destination
  290.                 call    GetChar
  291.                 jc      ArgComplete             ; jump if end of line
  292.                 jz      ArgCopyLoop             ; jump if \"
  293.                 cmp     al, ' '
  294.                 je      ArgComplete             ; whitespace terminates
  295.                 cmp     al, 9
  296.                 je      ArgComplete
  297.                 cmp     al, 13
  298.                 je      ArgComplete             ; whitespace terminates
  299.                 cmp     al, '"'
  300.                 jne     ArgCopyLoop
  301. ArgComplete:    call    ProcessArg              ; copy or expand argument
  302.                 jmp     SHORT NewArg
  303.  
  304. NoSbrkSpace:    jmp     abort@                  ; error jump
  305.  
  306. ;
  307. ; Here if quoted argument.
  308. ;
  309. ArgQuote:       call    GetChar
  310.                 jc      QuoteDone
  311.                 jz      QuoteNext
  312.                 cmp     al, '"'                 ; terminating quote ?
  313.                 je      QuoteDone
  314.                 cmp     al, 13                  ; hit end of line (CR)?
  315.                 je      QuoteDone
  316. QuoteNext:      call    ArgPushChar             ; store character in destination
  317.                 jmp     SHORT ArgQuote
  318. ;
  319. ; End of a quoted argument. Push terminating null, do not expand.
  320. ;
  321. QuoteDone:      xor     al, al
  322.                 call    ArgPushChar             ; push terminating null
  323.                 inc     dx                      ; bump arg count
  324.                 jmp     SHORT NewArg            ; go get more
  325.  
  326. ;------------------------------------------------------------------------------
  327. ;
  328. ; Here when done expanding command line. Go build the argv array.
  329. ;
  330. ArgCopyDone:    mov     ax, di                  ; ax = unused space
  331.                 sub     ax, wild_buff_max
  332.                 jz      ArgNoWaste              ; skip if all used
  333.                 push    dx
  334.                 push    di
  335. ifndef  __HUGE__
  336.                 mov     ds, SavedDS
  337. endif
  338.                 push    ax
  339.                 call    sbrk@                   ; release unused memory
  340.                 pop     cx                      ; toss parameter
  341.                 pop     di
  342.                 pop     dx
  343. ArgNoWaste:     lds     si, dword ptr wild_buff_addr
  344.                 mov     cx, di
  345.                 sub     cx, si                  ; cx = number of bytes in expanded line
  346.                 inc     dx                      ; count program name
  347.                 jmp     BuildArgv
  348.  
  349. ;------------------------------------------------------------------------------
  350. ;
  351. ; Routine to retrieve the next character from the command line.
  352. ;       Sets CF when end of line reached.
  353. ;       Sets ZF when \ character found (i.e. \")
  354. ;
  355. ;       bh.bit0 set if wildcard chars found (* or ?)
  356. ;       bh.bit1 set if \ character found (\")
  357. ;
  358. GetChar         proc    near
  359.  
  360.                 jcxz    GchEnd                  ; jump if no more
  361.                 lodsb
  362.                 dec     cx
  363.                 cmp     al, '\'                 ; escape ?
  364.                 je      GchEsc
  365.                 cmp     al, '?'
  366.                 je      GchWild
  367.                 cmp     al, '*'
  368.                 je      GchWild
  369. GchRet:         or      ah, 1                   ; clear CF and ZF
  370.                 ret
  371. GchWild:        test    bh, bh
  372.                 jnz     GchRet                  ; give up if \" has been found
  373.                 or      bh, 1
  374.                 ret
  375. GchEsc:         jcxz    GchRet                  ; check for \ at end of line
  376.                 cmp     byte ptr [si],'"'
  377.                 jne     GchRet                  ; only \" is special
  378.                 lodsb
  379.                 dec     cx
  380.                 mov     bh, 2                   ; set \ flag
  381.                 xor     ah, ah                  ; clear CF, set ZF
  382.                 ret
  383. GchEnd:         stc
  384.                 ret
  385.  
  386. GetChar         endp
  387.  
  388. ;------------------------------------------------------------------------------
  389. ;
  390. ; Routine to expand a wildcard parameter.
  391. ;
  392. ;       DS:SI   =       argument address
  393. ;       ES:DI   =       destination
  394. ; Returns:
  395. ;       CX      =       number of expanded arguments (0 = no match)
  396. ;
  397. WildExpand      proc    near
  398.  
  399.                 push    ds
  400.                 mov     wild_argument, si
  401.                 mov     wild_argument+2, ds
  402.                 mov     wild_destin, di
  403.                 mov     wild_destin+2, es
  404.                 mov     word ptr wild_argc, 0
  405. ;
  406. ; Find the length of the path prefix, if any.
  407. ;
  408.                 mov     bx, si
  409. WildFindPath:   lodsb
  410.                 and     al, al
  411.                 jz      WildEndPath
  412.                 cmp     al, '\'
  413.                 je      WildDelimiter
  414.                 cmp     al, ':'
  415.                 je      WildDelimiter
  416.                 cmp     al, '\'
  417.                 jne     WildFindPath
  418. WildDelimiter:  mov     bx, si                  ; save addr past last delimiter
  419.                 jmp     SHORT WildFindPath
  420. WildEndPath:    sub     bx, wild_argument
  421.                 mov     wild_path_len, bx
  422.  
  423.                 mov     ah, 4eh
  424.                 mov     cx, wild_attr           ; file attribute
  425.                 lds     dx, dword ptr wild_argument
  426.                 int     21h                     ; find first matching file ...
  427.                 jc      WildDone
  428. ;
  429. ; We have a matching file. Add it to the destination string (unless "." or "..")
  430. ;
  431. WildAddArg:
  432. ;
  433. ; If directories are included (10h set in wild_attr), ignore "." and ".."
  434. ;
  435. if      wild_attr  AND 16
  436.                 push    ss
  437.                 pop     ds
  438.                 lea     si,wild_ffblk.ff_name
  439.                 cmp     byte ptr [si],'.'       ; skip if doesn't start with "."
  440.                 jne     WildNoDir
  441.                 cmp     byte ptr [si+1],0       ; check for "."
  442.                 je      WildNameNext
  443.                 cmp     word ptr [si+1],'.'     ; check for ".."
  444.                 je      WildNameNext
  445. WildNoDir:
  446. endif
  447.  
  448.                 inc     word ptr wild_argc
  449.                 les     di, dword ptr wild_destin
  450.                 mov     cx, wild_path_len       ; prefix filename with path
  451.                 jcxz    WildCopyName
  452.                 lds     si, dword ptr wild_argument
  453. WildCopyPath:   lodsb
  454.                 call    ArgPushChar
  455.                 loop    WildCopyPath
  456. WildCopyName:   lea     si,wild_ffblk.ff_name   ; copy filename from ffblk
  457. WildNameLoop:   lods    byte ptr ss:[si]
  458.                 push    ax
  459.                 call    ArgPushChar             ; store char in destination
  460.                 pop     ax
  461.                 and     al, al                  ; continue until \0
  462.                 jnz     WildNameLoop
  463.                 mov     wild_destin, di
  464. WildNameNext:   mov     ah, 4fh
  465.                 int     21h                     ; find next matching file
  466.                 jnc     WildAddArg
  467. ;
  468. ; Done with expansion. Restore ES:DI, set CX, and return.
  469. ;
  470. WildDone:       mov     cx, wild_argc
  471.                 les     di, dword ptr wild_destin
  472.                 pop     ds
  473.                 ret
  474.  
  475. WildExpand      endp
  476.  
  477. ;------------------------------------------------------------------------------
  478. ;
  479. ; Routine to store a character in the destination string.
  480. ;
  481. ArgPushChar     proc    near
  482.  
  483.                 cmp     di, wild_buff_max       ; space available ?
  484.                 jae     ArgMoreSpace
  485.                 stosb                           ; yes --> store character
  486.                 ret
  487. ;
  488. ; No more argument space. Grab some more memory through sbrk.
  489. ;
  490. ArgMoreSpace:   push    ds
  491.                 push    es
  492.                 push    si
  493.                 push    di
  494.                 push    ax
  495.                 push    bx
  496.                 push    cx
  497.                 push    dx
  498.  
  499. ifndef  __HUGE__
  500.                 mov     ds, SavedDS
  501. endif
  502.                 mov     ax, wild_more_space
  503.                 add     wild_buff_size, ax      ; bump allocated size
  504.                 add     wild_buff_max, ax       ; bump end pointer
  505.                 push    ax
  506.                 call    sbrk@
  507.                 pop     cx
  508. if      LDATA
  509.                 and     ax, dx
  510. endif
  511.                 cmp     ax, -1
  512.                 je      NoArgSpace              ; abort if not enough space
  513.  
  514.                 pop     dx
  515.                 pop     cx
  516.                 pop     bx
  517.                 pop     ax
  518.                 pop     di
  519.                 pop     si
  520.                 pop     es
  521.                 pop     ds
  522.                 stosb                           ; store character
  523.                 ret
  524.  
  525. ArgPushChar     endp
  526.  
  527. ;------------------------------------------------------------------------------
  528. ;
  529. ; Not enough space to process the command line .... abort.
  530. ;
  531. NoArgSpace:     jmp     abort@
  532.  
  533. ;------------------------------------------------------------------------------
  534. ;
  535. ; Routine to process an argument.
  536. ;
  537. ProcessArg      proc    near
  538.  
  539.                 push    bx
  540.                 xor     al, al
  541.                 call    ArgPushChar             ; null-terminate
  542.                 pop     bx
  543.                 test    bh, 1                   ; wildcards present ?
  544.                 jnz     ArgWild
  545.                 inc     dx                      ; bump arg count
  546.                 ret
  547. ;
  548. ; We have a wildcard argument. Expand it.
  549. ;
  550. ArgWild:        push    cx
  551.                 push    [si]                    ; save word following argument
  552.                 mov     byte ptr [si],0         ; null-terminate argument
  553.                 xchg    si, wild_arg_src        ; si = argument address
  554.                 push    di
  555.                 mov     di, wild_arg_dst
  556.                 push    dx
  557.                 call    WildExpand
  558.                 pop     dx
  559.                 pop     bx
  560.                 and     cx, cx                  ; see if any matched
  561.                 jnz     ArgWildSome
  562.                 mov     di, bx                  ; none ---> use unexpanded argument
  563.                 mov     cx, 1                   ; bump arg count by 1
  564. ArgWildSome:    add     dx, cx
  565.                 mov     si, wild_arg_src
  566.                 pop     [si]                    ; restore word following argument
  567.                 pop     cx
  568.                 ret
  569.  
  570. ProcessArg      endp
  571.  
  572. ;------------------------------------------------------------------------------
  573. ;
  574. ; Build the argv array. [DS:SI] is the expanded command line, CX its length.
  575. ; DX has the number of arguments (including the program name).
  576. ;
  577. BuildArgv:      push    ds
  578.                 push    dx
  579.                 lds     dx, dword ptr wild_DTA_save
  580.                 mov     ah, 1ah
  581.                 int     21h                     ; switch to original DTA
  582.                 pop     dx
  583.                 pop     ds
  584.  
  585.                 add     sp, wild_frame_size     ; remove local variables
  586.  
  587.                 mov     es,SavedDS
  588.                 mov     es:[DGROUP:_argc@], dx
  589.                 inc     dx                      ; argv ends with a NULL pointer
  590.                 shl     dx, 1                   ;   argc * 2    (LDATA = 0)
  591. IF      LDATA
  592.                 shl     dx, 1                   ;   argc * 4    (LDATA = 1)
  593. ENDIF
  594.                 mov     bx, sp                  ; point to program name
  595.                 mov     bp, sp
  596.                 sub     bp, dx
  597.                 jb      NoArgSpace
  598.                 mov     sp, bp                  ; SS:BP = argv array address
  599.                 mov     word ptr es:[DGROUP:_argv@], bp
  600. IF      LDATA
  601.                 mov     word ptr es:[DGROUP:_argv@+2], ss
  602. ENDIF
  603.                 mov     [bp], bx                ; set argv[0] to program name
  604. IF      LDATA
  605.                 mov     [bp+2], ss              ; program name is on the stack
  606. ENDIF
  607.                 add     bp, dPtrSize
  608.  
  609. SetArgvX        label   near
  610.                 jcxz    SetLastArg
  611.                 mov     [bp], si                ; Set argv[n]
  612. IF      LDATA
  613.                 mov     [bp+2], ds
  614. ENDIF
  615.                 add     bp, dPtrSize
  616. CopyArg         label   near
  617.                 lodsb
  618.                 or      al, al
  619.                 loopnz  CopyArg
  620.                 jz      SetArgvX
  621. SetLastArg      label   near
  622.                 xor     ax, ax
  623.                 mov     [bp], ax
  624. IF      LDATA
  625.                 mov     [bp+2], ax
  626. ENDIF
  627.                 mov     ds, SavedDS
  628.  
  629. ;==============================================================================
  630. else
  631. ;==============================================================================
  632.  
  633.                 mov     ds, bp
  634.                 xchg    si, dx          ; DS: SI = Command Line address
  635.                 xchg    bx, cx          ; CX = Command Line size including \r
  636.                 mov     ax, bx
  637.                 mov     dx, ax          ; AX = BX = DX = 0
  638.                 inc     bx              ; BX = Nb of arguments (at least 1)
  639. Processing      label   near
  640.                 call    NextChar
  641.                 ja      NotQuote        ; Not a quote and there are more
  642. InString        label   near
  643.                 jb      BuildArgv       ; Command line is empty now
  644.                 cmp     al, 13
  645.                 je      EndArgument
  646.                 call    NextChar        ; \r    is an argument separator
  647.                 ja      InString        ; Not a quote and there are more
  648. NotQuote        label   near
  649.                 cmp     al, ' '
  650.                 je      EndArgument     ; Space is an argument separator
  651.                 cmp     al, 13
  652.                 je      EndArgument     ; \r    is an argument separator
  653.                 cmp     al, 9
  654.                 jne     Processing      ; \t    is an argument separator
  655. EndArgument     label   near
  656.                 xor     al, al          ; Space and TAB are argument separators
  657.                 jmp     short Processing
  658.  
  659. ;       Character test function used in SetArgs
  660. ;               On entry AL holds the previous character
  661. ;               On exit  AL holds the next character
  662. ;                        ZF on if the next character is quote (") and AL = 0
  663. ;                        CF on if end of command line and AL = 0
  664.  
  665. NextChar        PROC    NEAR
  666.                 or      ax, ax
  667.                 jz      NextChar0
  668.                 inc     dx              ; DX = Actual length of CmdLine
  669.                 stosb
  670.                 or      al, al
  671.                 jnz     NextChar0
  672.                 inc     bx              ; BX = Number of parameters
  673. NextChar0       label   near
  674.                 xchg    ah, al
  675.                 xor     al, al
  676.                 stc
  677.                 jcxz    NextChar2       ; End of command line --> CF ON
  678.                 lodsb
  679.                 dec     cx
  680.                 sub     al, '"'
  681.                 jz      NextChar2       ; Quote found --> AL = 0 and ZF ON
  682.                 add     al, '"'
  683.                 cmp     al,'\'
  684.                 jne     NextChar1       ; It is not a \
  685.                 cmp     byte ptr ds:[si], '"'
  686.                 jne     NextChar1       ; Only " is transparent after \
  687.                 lodsb
  688.                 dec     cx
  689. NextChar1       label   near
  690.                 or      si, si          ; Be sure both CF & ZF are OFF
  691. NextChar2       label   near
  692.                 ret
  693. NextChar        ENDP
  694.  
  695. ;       Invalid program name
  696.  
  697. BadProgName     label   near
  698.                 jmp     abort@
  699.  
  700. ;       Now, build the argv array
  701.  
  702. BuildArgv       label   near
  703.                 pop     cx
  704.                 add     cx, dx          ; CX = Argument area size
  705.                 mov     ds, SavedDS
  706.                 mov     _argc@, bx
  707.                 inc     bx              ; argv ends with a NULL pointer
  708.                 add     bx, bx          ;        argc * 2       (LDATA = 0)
  709. IF      LDATA
  710.                 add     bx, bx          ;        argc * 4       (LDATA = 1)
  711. ENDIF
  712.                 mov     si, sp
  713.                 mov     bp, sp
  714.                 sub     bp, bx
  715.                 jb      BadProgName
  716.                 mov     sp, bp          ; SS:BP = argv array address
  717.                 mov     word ptr _argv@, bp
  718. IF      LDATA
  719.                 mov     word ptr _argv@+2, ss
  720. ENDIF
  721. SetArgvX        label   near
  722.                 jcxz    SetLastArg
  723.                 mov     [bp], si        ; Set argv[n]
  724. IF      LDATA
  725.                 mov     [bp+2], ss
  726. ENDIF
  727.                 add     bp, dPtrSize
  728. CopyArg         label   near
  729.                 lods    byte ptr ss:[si]
  730.                 or      al, al
  731.                 loopnz  CopyArg
  732.                 jz      SetArgvX
  733. SetLastArg      label   near
  734.                 xor     ax, ax
  735.                 mov     [bp], ax
  736. IF      LDATA
  737.                 mov     [bp+2], ax
  738. ENDIF
  739.  
  740. ;==============================================================================
  741. endif           ;       ifdef WILD
  742. ;==============================================================================
  743.  
  744. ;       Restore caller context and exit
  745.  
  746.                 mov     ds,SavedDS
  747.                 mov     si,SavedSI
  748.                 mov     di,SavedDI
  749.                 push    word ptr SavedReturn2
  750.                 push    word ptr SavedDS2
  751.                 mov     ax,__argc
  752.                 mov     __C0argc,ax
  753. IF      LDATA
  754.                 mov     ax,word ptr __argv+2
  755.                 mov     word ptr __C0argv+2,ax
  756. ENDIF
  757.                 mov     ax,word ptr __argv
  758.                 mov     word ptr __C0argv,ax
  759.  
  760.                 jmp     word ptr SavedReturn
  761.  
  762.                 endp
  763.                 ends
  764.  
  765.                 END
  766.