home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SOURCE / STARTUP / DOS / STDARGV.AS_ / STDARGV.AS
Encoding:
Text File  |  1993-02-08  |  16.5 KB  |  873 lines

  1.     page    ,132
  2.     title    stdargv - standard & wildcard _setargv routine
  3. ;***
  4. ;stdargv.asm - standard & wildcard _setargv routine
  5. ;
  6. ;    Copyright (c) 1985-1992, Microsoft Corporation.  All rights reserved.
  7. ;
  8. ;Purpose:
  9. ;    processes program command line, with or without wildcard expansion
  10. ;
  11. ;*******************************************************************************
  12.  
  13.  
  14. ifdef    WILDCARD
  15.     name    _setargv    ; wildcard _setargv routine
  16. else
  17.     name    stdargv     ; standard _setargv routine
  18. endif
  19.  
  20. ifdef    WILDCARD
  21. ?DF    =    1        ; tell cmacros.inc we want to define our own segments
  22. endif
  23.  
  24.     .xlist
  25. include version.inc
  26. include cmacros.inc
  27. include msdos.inc
  28. include defsegs.inc
  29. include rterr.inc
  30.     .list
  31.  
  32. ifdef _WINDOWS
  33.  
  34. _MAX_PATH equ 260            ; max path (should match stdlib.h)
  35.  
  36. extrn    pascal    GETMODULEFILENAME:far    ; get argv[0]
  37. extrn    __myalloc:near            ; allocation routine for arguments
  38.  
  39. endif
  40.  
  41. ifdef FARSTACK
  42. ife sizeD
  43.     error <You cannot have a far stack in Small or Medium memory models.>
  44. endif
  45. endif
  46.  
  47. ifdef    WILDCARD        ; **********************************************
  48.  
  49. CrtDefSegs <code, data>
  50. CrtDefSegs <nmsg>
  51.  
  52. codeOFFSET equ    <offset _TEXT:>
  53. dataOFFSET equ    <offset DGROUP:>
  54.  
  55. ; Message used by ___setargv (wildcard version of __setargv)
  56.  
  57. sBegin    nmsg
  58. assumes ds,data
  59.  
  60.     _RTERR    _RT_SPACEARG, _RT_SPACEARG_TXT, _RT_STANDARD    ; 'not enough space for arguments'
  61.  
  62. sEnd
  63.  
  64. sBegin    npad
  65. assumes ds,data
  66.     dw    -1
  67. ; no padding for now;
  68. ; MAX padding would be
  69. ;    db    25 dup(0)
  70. sEnd
  71.  
  72. externP _cwild            ; Wildcard Expander
  73. externNP _amsg_exit        ; error handler (unable to allocate)
  74.  
  75. endif                ; WILDCARD    ; **********************************************
  76.  
  77.  
  78. sBegin    data
  79. assumes ds,data
  80.  
  81. C_CR    equ    0DH        ; ASCII carriage return
  82.  
  83. C_BLANK equ    ' '        ; ASCII space character
  84. C_TAB    equ    09h        ; ASCII horizontal tab character
  85.  
  86. C_QUOTE equ    '"'        ; ASCII (double) Quote Charater
  87. C_BACKSLASH equ '\'             ; ASCII backward slash character
  88.  
  89. externDP __argv         ; argument string array address
  90. externW __argc            ; count of argument strings
  91. externW _psp            ; address of Program Segment Prefix
  92. externD _pgmptr         ; far ptr to name of program
  93.  
  94. ifdef _BAT16
  95. externD __cmdLine        ; cmdLine ptr
  96. endif
  97.  
  98.  
  99. ifdef _WINDOWS
  100. ifdef _WINDLL
  101. externW _hModule        ; identifies module
  102. else
  103. externW _hInstance        ; identifies instance of module
  104. endif
  105. else    ;!_WINDOWS
  106. externW _osversion        ; address of OS version
  107. endif
  108.  
  109.  
  110. staticCP retadr,0        ; return address
  111.  
  112.  
  113. ifdef    WILDCARD        ; **********************************************
  114.  
  115. dta_flag db    0        ; Has DMA been set yet?
  116.  
  117. file_reserv db    21 dup (0)
  118. file_attrib db    0
  119. file_time dw    0
  120. file_date dw    0
  121. file_sizel dw    0
  122. file_sizeh dw    0
  123. file_name db    13 dup (0)
  124.  
  125. endif                ; WILDCARD    ; **********************************************
  126.  
  127.  
  128. sEnd
  129.  
  130. ; ****************************************
  131.  
  132. jmps    MACRO    target
  133.     jmp    short target
  134.     ENDM
  135.  
  136. lje    MACRO    target
  137.     LOCAL    temp
  138.     jne    temp
  139.     jmp    target
  140. temp:
  141.     ENDM
  142.  
  143.  
  144. DELIM    MACRO    target
  145.     cmp    al,C_CR     ;; Test for end-of-line character
  146.     je    target
  147.     or    al,al        ;; Either Carriage Return or Null
  148.     je    target
  149.     ENDM
  150.  
  151. LDELIM    MACRO    target
  152.     cmp    al,C_CR     ;; Test for end-of-line character
  153.     lje    target
  154.     or    al,al        ;; Either Carriage Return or Null
  155.     lje    target
  156.     ENDM
  157.  
  158. ; ****************************************
  159.  
  160. sBegin    code
  161.  
  162. assumes ds,data
  163. ifdef FARSTACK
  164. assumes ss,nothing
  165. else
  166. assumes ss,data
  167. endif
  168. assumes cs,code
  169.  
  170. ifdef  _WINDOWS
  171.     if    sizeD
  172.     externP  _GetDGROUP
  173.     endif
  174. endif
  175.  
  176. page
  177. ;***
  178. ;_setargv, __setargv - set up "argc" and "argv" for C programs
  179. ;
  180. ;Purpose:
  181. ;    Gets the command line from the PSP and moves the information
  182. ;    to its place on the stack.
  183. ;
  184. ;    SIDE EFFECTS:
  185. ;        Allocates space on the stack for the argument strings
  186. ;        and a list of pointers to them.
  187. ;    ASSUMPTIONS:
  188. ;        Under DOS 2, there is no argv[0] string, so we store a null
  189. ;        char ('\0').
  190. ;
  191. ;        Under DOS 3 and later, the argv[0] string is found in the
  192. ;        environment segment, after the double null that terminates
  193. ;        that segment and after a word of value 1.  The rest of the
  194. ;        command line is found in the Program Segment Prefix at
  195. ;        offset 81H, and is terminated by a 0DH.  This command "tail"
  196. ;        cannot be greater than 126 bytes in length.
  197. ;
  198. ;        Quote marks and backslashes are treated specially.  A quoted
  199. ;        string is passed as a single argument, not including the
  200. ;        opening and closing quote characters.  A quote may be imbedded
  201. ;        in a string by placing an odd number of backslashes (`\')
  202. ;        before it.  Each pair of backslashes which precedes a quote
  203. ;        results in a single backslash in the resultant string.
  204. ;        An even number of backslashes followed by a quote results in
  205. ;        half that many backslashes, and the quote begins or ends the
  206. ;        quoted part of the string as is appropriate.  Backslashes not
  207. ;        followed by a quote are treated normally.
  208. ;
  209. ;        [""] ==> []
  210. ;        [\"] ==> ["]
  211. ;        [" \" "] == [ " ]
  212. ;        [" \\"] == [ \]
  213. ;        [" \\ "] == [ \\ ]
  214. ;        [" \\\" "] == [ \" ]
  215. ;        etc.
  216. ;        ["one two three"] ==> [one two three]
  217. ;        [one" two "three] ==> [one two three]
  218. ;        [o"ne two t"hree] ==> [one two three]
  219. ;        ["one \"two\" three"] ==> [one "two" three]
  220. ;        ["x\\\"x"] ==> [x\"x]
  221. ;
  222. ;Entry:
  223. ;
  224. ;Exit:
  225. ;    "argv" points to a null-terminated list of pointers to ASCIZ
  226. ;    strings, each of which is an argument from the command line.
  227. ;    "argc" is the number of arguments.  The strings are copied from
  228. ;    the Program Segment Prefix into space allocated on the stack.
  229. ;    The list of pointers is also located on the stack.
  230. ;
  231. ;Uses:
  232. ;    All registers except DS, SS, and BP are modified
  233. ;    Note especially that SI and DI are NOT preserved!
  234. ;
  235. ;Exceptions:
  236. ;
  237. ;*******************************************************************************
  238.  
  239. ifdef    WILDCARD        ; **********************************************
  240.  
  241. labelP    <PUBLIC,__setargv>
  242.  
  243. else                ; **********************************************
  244.  
  245. labelP    <PUBLIC,_setargv>
  246.  
  247. endif                ; WILDCARD    ; **********************************************
  248.  
  249.     pop    word ptr [retadr] ; get return address (offset)
  250. if    sizeC
  251.     pop    word ptr [retadr+2] ; get return address (segment)
  252. endif
  253.  
  254. ifdef    _WINDOWS
  255. ifndef _BAT16
  256.  
  257. ;
  258. ; In windows, get argv[0] from the system, not from the DOS segment
  259. ;
  260.     mov    ax,_MAX_PATH        ; maximum length of path
  261.     mov    cx,_RT_SPACEARG     ; Out of heap space
  262.     call    __myalloc        ; get argv[0] memory
  263.                     ; *** DIES ON ERROR ***
  264. ifdef    WILDCARD
  265.     inc    ax            ; room for wildcard flag
  266. endif
  267.     mov    word ptr [_pgmptr+2],dx ; set global variable "_pgmptr"
  268.     mov    word ptr [_pgmptr],ax
  269.  
  270.     push    dx            ; save ptr across call
  271.     push    ax
  272.  
  273. ifdef    _WINDLL
  274.     push    _hModule        ; module instance
  275. else
  276.     push    _hInstance        ; module instance
  277. endif
  278.     push    dx            ; address of name buffer
  279.     push    ax
  280.     mov    ax,_MAX_PATH        ; size of buffer
  281.     push    ax
  282.     call    GETMODULEFILENAME    ; ax = length of actual string
  283.     ; no error return defined
  284.  
  285.     pop    bx
  286.     pop    es            ; es:bx = pointer to string
  287.     add    bx,ax            ; es:bx = end of string
  288.     mov    byte ptr es:[bx],0    ; store a final null byte
  289.  
  290.     mov    dx,1            ; dx = number of bytes in argv[0]
  291.  
  292. endif  ;!_BAT16
  293. else    ;!_WINDOWS
  294. ;
  295. ; Check DOS version.
  296. ;
  297.     mov    ax,[_osversion] ; ax = OS version number
  298.     mov    dx,1        ; dx = number of bytes in argv[0] if DOS 2.x
  299.     cmp    al,2
  300.     je    dos_two
  301.  
  302.     mov    es,_psp
  303.     mov    es,es:[DOS_envp] ; get environment segment
  304.     mov    word ptr [_pgmptr+2],es ; set global variable "_pgmptr"
  305.     xor    ax,ax
  306.     cwd            ; DX=0
  307.     mov    cx,8000H
  308.     xor    di,di        ; scan from beginning of environment
  309. find_env_end:
  310.     repne    scasb
  311.     scasb
  312.     jne    find_env_end
  313. ;
  314.     inc    di        ; skip count word (always 0x0001)
  315.     inc    di
  316.     mov    word ptr [_pgmptr],di ; set global variable "_pgmptr"
  317.     mov    cx,-1
  318.     repne    scasb
  319.     not    cx
  320.     mov    dx,cx        ; DX=number of bytes in argv[0]
  321.  
  322. endif    ;_WINDOWS
  323.  
  324. dos_two:
  325. ifdef FARSTACK
  326.     push    ds
  327.     pop    es
  328.     assumes es,data     ; set ES=DGROUP
  329. endif
  330. ifndef  _BAT16
  331.     mov    di,1        ; always start with one argument
  332.     mov    si,81H
  333.     mov    ds,_psp
  334.  
  335. else    ; _BAT16
  336.     xor      dx,dx        ;no byte yet
  337.     xor    di,di        ;always start with no arguments
  338.     lds    si,ss:[__cmdLine] ;* Point to beg of command line
  339. endif    ; _BAT16
  340.  
  341.     assumes ds,nothing
  342. ;*
  343. ;*    Count the command tail arguments
  344. ;*
  345. ;
  346. ;    DI will count the number of arguments
  347. ;    DX will count the number of bytes needed for the arguments
  348. ;        (not including the null terminators)
  349. ;
  350. arg100:
  351. arg110:
  352.     lodsb
  353.     cmp    al,C_BLANK
  354.     je    arg110
  355.     cmp    al,C_TAB
  356.     je    arg110
  357.  
  358.     DELIM    arg400
  359.  
  360.     inc    di        ; Another argument
  361. ;
  362. ; Parse an argument
  363. ;
  364. arg200:
  365.     dec    si        ; back up to reload character
  366. arg210:
  367.     lodsb
  368.  
  369.     cmp    al,C_BLANK
  370.     je    arg100
  371.     cmp    al,C_TAB
  372.     je    arg100        ; white space terminates argument
  373.  
  374.  
  375.     DELIM    arg400
  376.  
  377.     cmp    al,C_QUOTE
  378.     je    arg310
  379.  
  380.     cmp    al,C_BACKSLASH
  381.     je    arg220
  382.  
  383.  
  384.  
  385.     inc    dx
  386.     jmps    arg210
  387. ;
  388. ; Count backslashes
  389. ;
  390. arg220:
  391.     xor    cx,cx
  392. arg221:
  393.     inc    cx        ; CX counts the backslashes
  394.     lodsb
  395.     cmp    al,C_BACKSLASH
  396.     je    arg221
  397. ;
  398.     cmp    al,C_QUOTE
  399.     je    arg230
  400.  
  401.     add    dx,cx        ; not followed by `"' -- treat `\'s normally
  402.     jmp    arg200
  403. ;
  404. arg230:
  405.     mov    ax,cx
  406.     shr    cx,1
  407.     adc    dx,cx        ; add 1 for every pair of backslashes
  408.     test    al,1        ; plus 1 for the " if odd number of \
  409.     jnz    arg210        ; " was escaped with a \
  410.     jmps    arg310        ; " opens a quoted substring
  411. ;
  412. ; Enter a quoted string
  413. ;
  414. arg300:
  415.     dec    si        ; back up to reload character
  416. arg310:
  417.     lodsb
  418.  
  419.     DELIM    arg400
  420.  
  421.     cmp    al,C_QUOTE
  422.     je    arg210        ; end of quoted portion of string
  423.  
  424.     cmp    al,C_BACKSLASH
  425.     je    arg320
  426.  
  427.  
  428.     inc    dx
  429.     jmp    arg310
  430. ;
  431. ; Count backslashes
  432. ;
  433. arg320:
  434.     xor    cx,cx
  435. arg321:
  436.     inc    cx        ; CX counts the backslashes
  437.     lodsb
  438.     cmp    al,C_BACKSLASH
  439.     je    arg321
  440. ;
  441.     cmp    al,C_QUOTE
  442.     je    arg330
  443.  
  444.     add    dx,cx        ; not followed by `"' -- treat `\'s normally
  445.     jmp    arg300
  446. ;
  447. arg330:
  448.     mov    ax,cx
  449.     shr    cx,1
  450.     adc    dx,cx        ; add 1 for every pair of backslashes
  451.     test    al,1        ; plus 1 for the " if odd number of \
  452.     jnz    arg310        ; " was escaped with a \
  453.     jmps    arg210        ; " closes a quoted substring
  454. ;
  455. ; Command line is fully parsed - compute number of bytes needed
  456. ;
  457. arg400:
  458. ;
  459. ;    Number of bytes needed =
  460. ;        Number of bytes used to make strings +
  461. ;        Number of bytes used to terminate strings +
  462. ;        sizeof(DATAPTR) * ( number of arguments + 1 )
  463. ;
  464. ifdef FARSTACK
  465.     push    es
  466. else
  467.     push    ss
  468. endif ;FARSTACK
  469.     pop    ds        ; Restore DS = DGROUP
  470.     assumes ds,data
  471.  
  472.     mov    __argc,di    ; Store number of arguments
  473.  
  474.     add    dx,di        ; add in terminator bytes
  475. ifdef    WILDCARD
  476.     add    dx,di        ; add in Wildcard flag bytes
  477. endif
  478.     inc    di        ; add one for NULL pointer
  479.     shl    di,1
  480. if    sizeD
  481.     shl    di,1
  482. endif
  483.     add    dx,di        ; add space for pointers to space for chars
  484.  
  485.     inc    dx
  486.     and    dl,not 1    ; Round up to an even number of bytes
  487. ;
  488. ;    Allocate space on the stack
  489. ;
  490. ;    DX is the total number of bytes needed for strings and pointers
  491. ;    DI is the number of bytes needed for the pointers
  492. ;
  493.     sub    sp,dx
  494.     mov    ax,sp
  495.  
  496.     mov    word ptr (__argv),ax
  497. if    sizeD
  498.     mov    word ptr (__argv+2),ss
  499. endif
  500. ;
  501. ;    Copy argument strings and addresses onto heap/stack
  502. ;        Address table is on the top, strings below that
  503. ;
  504.     mov    bx,ax
  505.     add    di,bx
  506.  
  507.     push    ss        ; ES=SS
  508.     pop    es        ; ES:DI is where the string copies will go
  509. ifndef FARSTACK
  510.     assumes es,data
  511. endif
  512.  
  513. ifndef  _BAT16
  514. ;
  515. ;    DS:SI    points to the argv[0]
  516. ;
  517. ;    ES:BX    points to where argv[0],argv[1],argv[2],... go
  518. ;    ES:DI    points to where *argv[0],*argv[1],*argv[2],... go
  519. ; For wildcard version only:
  520. ;    ES:DX    points to the wildcard flag character (prepended to argument)
  521. ;        during the creation of each argument
  522. ;
  523.  
  524. ifdef    _WINDOWS
  525.  
  526.     ; move the pointer, no need to move the string
  527.     lds    si,[_pgmptr]    ; copy argv[0], either fake or from env seg
  528.     assumes ds,nothing
  529.  
  530. ifdef    WILDCARD
  531.     dec    si        ; room for wildcard flag
  532. endif
  533.     mov    ss:[bx],si    ; argv[0] - offset part
  534. if    sizeD
  535.     mov    ss:[bx+2],ds    ; argv[0] - segment part
  536.     add    bx,4
  537. else
  538.     inc    bx
  539.     inc    bx
  540. endif
  541.  
  542. else    ;!_WINDOWS
  543.  
  544.     mov    ss:[bx],di    ; argv[i] - offset part
  545. if    sizeD
  546.     mov    ss:[bx+2],ss    ; argv[i] - segment part
  547.     add    bx,4
  548. else
  549.     inc    bx
  550.     inc    bx
  551. endif
  552.  
  553.     lds    si,[_pgmptr]    ; copy argv[0], either fake or from env seg
  554.     assumes ds,nothing
  555.  
  556. ifdef    WILDCARD
  557.     movsb
  558.     dec    si        ; copy first character as quote flag
  559. endif
  560.  
  561. copy_argv0:
  562.     lodsb
  563.     stosb
  564.     or    al,al
  565.     jnz    copy_argv0
  566.  
  567. endif    ;_WINDOWS
  568.  
  569.  
  570. ;
  571. ;    DS:SI    points to the raw command tail string
  572. ;
  573.  
  574. ifdef FARSTACK
  575.  
  576.     ifdef  _WINDOWS
  577.     push    ax
  578.     callcrt _GetDGROUP
  579.     mov    ds, ax        ; DS = DGROUP
  580.     pop    ax
  581.     else    ;not _WINDOWS
  582.     mov    si, DGROUP
  583.     mov    ds, si        ; DS = DGROUP
  584.     endif   ;not _WINDOWS
  585.  
  586.     assumes ds, data
  587.     mov    ds, [_psp]
  588.     assumes ds, nothing    ; let DS = psp
  589. else
  590.     mov    ds,ss:[_psp]    ; DS:SI is where the source strings are
  591. endif ;FARSTACK
  592.     mov    si,81H        ; address of strings
  593.  
  594. else    ; _BAT16
  595.     lds    si,ss:[__cmdLine] ;* Point to the comand line again
  596. endif    ; _BAT16
  597.  
  598.     assumes ds,nothing
  599.  
  600.     jmps    arg510
  601. ;
  602. ;    Skip blanks
  603. ;
  604. arg500:
  605.     xor    ax,ax
  606.     stosb
  607. arg510:
  608.     lodsb
  609.     cmp    al,C_BLANK
  610.     je    arg510
  611.     cmp    al,C_TAB
  612.     je    arg510
  613.  
  614. ifdef    WILDCARD
  615.     LDELIM    arg810
  616. else
  617. if    sizeD
  618.     LDELIM    arg810
  619. else
  620.     DELIM    arg810
  621. endif
  622. endif
  623.  
  624.     mov    ss:[bx],di
  625. if    sizeD
  626.     mov    ss:[bx+2],ss
  627.     add    bx,4
  628. else
  629.     inc    bx
  630.     inc    bx
  631. endif
  632.  
  633. ifdef    WILDCARD
  634.     mov    dx,di
  635.     stosb            ; initialize wildcard flag
  636. endif
  637. ;
  638. ;
  639. ; Parse an argument
  640. ;
  641. arg600:
  642.     dec    si        ; back up to reload character
  643. arg610:
  644.     lodsb
  645.  
  646.     cmp    al,C_BLANK
  647.     je    arg500
  648.     cmp    al,C_TAB
  649.     je    arg500        ; white space terminates argument
  650.  
  651.     DELIM    arg800
  652.  
  653.     cmp    al,C_QUOTE
  654.     je    arg710x
  655.  
  656.     cmp    al,C_BACKSLASH
  657.     je    arg620
  658.  
  659.  
  660.     stosb
  661.     jmps    arg610
  662. ;
  663. ; Count backslashes
  664. ;
  665. arg620:
  666.     xor    cx,cx
  667. arg621:
  668.     inc    cx        ; CX counts the backslashes
  669.     lodsb
  670.     cmp    al,C_BACKSLASH
  671.     je    arg621
  672. ;
  673.     cmp    al,C_QUOTE
  674.     je    arg630
  675.  
  676.     mov    al,C_BACKSLASH
  677.     rep    stosb        ; not followed by `"' -- treat `\'s normally
  678.     jmp    arg600
  679. ;
  680. arg630:
  681.     mov    al,C_BACKSLASH
  682.     shr    cx,1
  683.     rep    stosb
  684.     jnc    arg710x     ; " opens a quoted substring
  685.     mov    al,C_QUOTE
  686.     stosb
  687.     jmp    arg610        ; " was escaped with a \
  688. ;
  689. ; Enter a quoted string
  690. ;
  691. ifdef    WILDCARD
  692. arg710x:
  693.     inc    si        ; undoes the "DEC SI" between arg700 and arg710
  694. endif
  695.  
  696. arg700x:
  697.  
  698. ifdef    WILDCARD
  699.     xchg    dx,di        ; set the wildcard flag character to `"'
  700.     mov    al,C_QUOTE
  701.     stosb
  702.     dec    di
  703.     xchg    dx,di
  704. endif
  705.  
  706. arg700:
  707.     dec    si        ; back up to reload character
  708.  
  709. ifndef    WILDCARD
  710. arg710x:
  711. endif
  712.  
  713. arg710:
  714.     lodsb
  715.  
  716.     DELIM    arg800
  717.  
  718.     cmp    al,C_QUOTE
  719.     je    arg610        ; end of quoted portion of string
  720.  
  721.     cmp    al,C_BACKSLASH
  722.     je    arg720
  723.  
  724.  
  725.     stosb
  726.     jmp    arg710
  727. ;
  728. ; Count backslashes
  729. ;
  730. arg720:
  731.     xor    cx,cx
  732. arg721:
  733.     inc    cx        ; CX counts the backslashes
  734.     lodsb
  735.     cmp    al,C_BACKSLASH
  736.     je    arg721
  737. ;
  738.     cmp    al,C_QUOTE
  739.     je    arg730
  740.  
  741.     mov    al,C_BACKSLASH
  742.     rep    stosb        ; not followed by `"' -- treat `\'s normally
  743.     jmp    arg700x
  744. ;
  745. arg730:
  746.     mov    al,C_BACKSLASH
  747.     shr    cx,1
  748.     rep    stosb        ; store 1 for every pair of backslashes
  749.     jnc    arg610        ; " closes a quoted substring
  750.     mov    al,C_QUOTE    ; " was escaped with a \
  751.     stosb
  752.     jmps    arg710x
  753. ;
  754. ; Terminate last argument string, terminate list of argument pointers
  755. ;
  756. arg800:
  757.     xor    ax,ax
  758.     stosb            ; null-terminate final argument
  759. arg810:
  760.  
  761. ifdef FARSTACK
  762.     ifdef  _WINDOWS
  763.     callcrt _GetDGROUP
  764.     mov    ds, ax
  765.     else
  766.     mov    ax, DGROUP
  767.     mov    ds, ax
  768.     endif
  769. else
  770.     push    ss        ; default is SS == DGROUP
  771.     pop    ds
  772. endif
  773.     assumes ds,data
  774.  
  775. ifdef FARSTACK
  776.     mov    word ptr ss:[bx],0
  777.     mov    word ptr ss:[bx+2],0
  778. else
  779.     mov    word ptr [bx],0 ; add null pointer to __argv[]
  780. if    sizeD
  781.     mov    word ptr [bx+2],0
  782. endif
  783. endif ;FARSTACK
  784.  
  785. ifndef    WILDCARD
  786.     jmp    [retadr]    ; THE END
  787. else
  788.     call    _cwild
  789.     test    ax,ax
  790.     jz    no_arg_err
  791.  
  792.     mov    ax,_RT_SPACEARG ; 'not enough space for arguments'
  793.     jmp    _amsg_exit    ;
  794.  
  795. no_arg_err:
  796.     jmp    [retadr]
  797.  
  798. page
  799. ;***
  800. ;_find(dir) - find first matching file name against pattern "dir"
  801. ;
  802. ;Purpose:
  803. ;    _find(dir) - Find first matching file name against pattern "dir"
  804. ;    If dir == NULL, then get next match for current pattern.
  805. ;
  806. ;Entry:
  807. ;    dir    = DATA PTR of pattern to match
  808. ;
  809. ;Exit:
  810. ;    AX    = the address of a static area containing the file name if a
  811. ;          match was found.  Returns NULL if no match was found.
  812. ;
  813. ;Uses:
  814. ;    CX,DX, [dta_flag].
  815. ;
  816. ;Exceptions:
  817. ;
  818. ;*******************************************************************************
  819.  
  820. cProc    _find,<PUBLIC>
  821.     parmdp    dir
  822. cBegin
  823.     test    [dta_flag],-1
  824.     jnz    not_very_first
  825.  
  826.     mov    [dta_flag],-1
  827. ;
  828. ;    Set DTA, where the match structure is returned
  829. ;
  830.     mov    dx,dataOFFSET file_reserv
  831.     callos    setdma
  832. ;
  833. not_very_first:
  834.     mov    ah,DOS_findnext ; assume not first
  835.  
  836. if    sizeD
  837.     push    ds
  838.     lds    dx,dir
  839.     mov    cx,ds
  840.     jcxz    find_next
  841. else
  842.     mov    dx,dir
  843.     test    dx,dx
  844.     jz    find_next
  845. endif
  846.     mov    cx,A_D        ; match directories as well as files
  847.     mov    ah,DOS_findfirst
  848. find_next:
  849.     callos
  850. if    sizeD
  851.     pop    ds
  852. endif
  853.     mov    ax,dataOFFSET file_name
  854. if    sizeD
  855.     mov    dx,ds
  856. endif
  857.     jnc    retname
  858.  
  859.     xor    ax,ax        ; return 0 for no more matches
  860. if    sizeD
  861.     cwd
  862. endif
  863.  
  864. retname:
  865.  
  866. cEnd
  867.  
  868. endif                ;    WILDCARD    ; ***********************************************
  869.  
  870. sEnd    code
  871.  
  872.     end
  873.