home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / Fortran.51 / DISK5 / DOS / STDARGV.AS$ / STDARGV.bin
Text File  |  1989-10-24  |  15KB  |  758 lines

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