home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / Fortran.51 / DISK5 / OS2 / STDARGV.AS$ / STDARGV.bin
Text File  |  1989-08-31  |  15KB  |  770 lines

  1.     page    ,132
  2.     title    stdargv.asm - OS/2 standard & wildcard _setargv routine
  3. ;***
  4. ;stdargv.asm - OS/2 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. ; _SSNEDS flag set means SS not necessarily equal to DS; this requires
  14. ; special processing to preserve the value of DS in places
  15. ifdef FARSTACK
  16.     _SSNEDS equ 1
  17. else
  18.     _SSNEDS equ 0
  19. endif
  20.  
  21. ifdef    WILDCARD
  22.     name    _setargv    ; wildcard _setargv routine
  23. else
  24.     name    stdargv     ; standard _setargv routine
  25. endif
  26.  
  27.     .xlist
  28. include version.inc
  29. include cmacros.inc
  30. include msdos.inc
  31. include rterr.inc
  32.     .list
  33.  
  34. ifdef FARSTACK
  35. ife sizeD
  36.     error <You cannot have a far stack in Small or Medium memory models.>
  37. endif
  38. endif
  39.  
  40. sBegin    data
  41. assumes ds,data
  42.  
  43. C_BLANK equ    ' '        ; ASCII space character
  44. C_TAB    equ    09h        ; ASCII horizontal tab character
  45.  
  46. C_QUOTE equ    '"'        ; ASCII (double) Quote Charater
  47. C_BACKSLASH equ '\'             ; ASCII backward slash character
  48.  
  49. externDP __argv         ; argument string array address
  50. externW __argc            ; count of argument strings
  51. externW _aenvseg        ; environment segment
  52. externW _acmdln         ; offset of command line in env. seg.
  53. externD _pgmptr         ; far pointer to program name
  54.  
  55. staticW cmdstart,0        ; start of command line string
  56.  
  57. ife   _SSNEDS
  58. staticCP retadr,0        ; return address
  59. endif
  60.  
  61. ifdef    WILDCARD
  62.  
  63. staticW findhandle,1        ; handle used for wildcard matching
  64.  
  65. FileFindBuf struc
  66. create_date dw    ?        ;* date of file creation
  67. create_time dw    ?        ;* time of file creation
  68. access_date dw    ?        ;* date of last access
  69. access_time dw    ?        ;* time of last access
  70. write_date dw    ?        ;* date of last write
  71. write_time dw    ?        ;* time of last write
  72. file_size dd    ?        ;* file size (end of data)
  73. falloc_size dd    ?        ;* file allocated size
  74. attributes dw    ?        ;* attributes of the file
  75. string_len db    ?        ;* returned length of ascii name str.
  76. file_name db    257 dup (?)    ;* name string
  77. FileFindBuf ends
  78.  
  79. findbuf FileFindBuf <>        ;* struct FileFindBuf findbuf;
  80.  
  81. endif                ;    WILDCARD
  82.  
  83. sEnd    data
  84.  
  85. ;=========================================
  86.  
  87. ifdef    WILDCARD
  88.     extrn    DOSFINDFIRST:far
  89.     extrn    DOSFINDNEXT:far
  90.     externP _cwild        ; Wildcard Expander
  91. endif
  92.  
  93. ;=========================================
  94.  
  95. jmps    MACRO    target
  96.     jmp    short target
  97.     ENDM
  98.  
  99. lje    MACRO    target
  100.     LOCAL    temp
  101.     jne    temp
  102.     jmp    target
  103. temp:
  104.     ENDM
  105.  
  106. DELIM    MACRO
  107.     or    al,al        ;; Test for end-of-line character (null)
  108.     ENDM
  109.  
  110. ;=========================================
  111.  
  112.  
  113. sBegin    code
  114.  
  115. externNP _stdalloc        ; routine to allocate heap memory
  116. externNP _amsg_exit        ; error handler (unable to allocate)
  117.  
  118. assumes ds,data
  119. if    _SSNEDS
  120. assumes ss,nothing
  121. else
  122. assumes ss,data
  123. endif ;_SSNEDS
  124. assumes cs,code
  125.  
  126. page
  127. ;***
  128. ;_setargv, __setargv - set up "argc" and "argv" for C programs
  129. ;
  130. ;Purpose:
  131. ;    Read the command line and create the argv array for C
  132. ;    programs.
  133. ;
  134. ;Entry:
  135. ;    Arguments are retrieved from the program command line.
  136. ;
  137. ;Exit:
  138. ;    "argv" points to a null-terminated list of pointers to ASCIZ
  139. ;    strings, each of which is an argument from the command line.
  140. ;    "argc" is the number of arguments.  The strings are copied from
  141. ;    the environment segment into space allocated on the heap/stack.
  142. ;    The list of pointers is also located on the heap or stack.
  143. ;
  144. ;Uses:
  145. ;
  146. ;Exceptions:
  147. ;
  148. ;*******************************************************************************
  149.  
  150.  
  151. ifdef    WILDCARD        ; **********************************************
  152.  
  153. labelP    <PUBLIC,__setargv>
  154.  
  155. else                ; **********************************************
  156.  
  157. labelP    <PUBLIC,_setargv>
  158.  
  159. endif                ; WILDCARD    ; **********************************************
  160.  
  161. ife _SSNEDS
  162.     pop    word ptr [retadr] ; get return address (offset)
  163.  
  164. if    sizeC
  165.     pop    word ptr [retadr+2] ; get return address (segment)
  166. endif
  167. endif ;_SSNEDS
  168.  
  169.     mov    ax,_acmdln
  170. if   _SSNEDS
  171.     push    ds
  172.     pop    es
  173.     assumes es,data
  174. endif ;_SSNEDS
  175.     mov    ds,_aenvseg
  176.     assumes ds,nothing
  177.  
  178.     mov    si,ax
  179. ;
  180. ;    If there is no argument string, use the
  181. ;    program name for the command line string.
  182. ;    Scan back for the null before "PgmPtr"
  183. ;
  184. find_argv0:
  185.     dec    si
  186.     jz    found_argv0
  187.     cmp    byte ptr ds:[si-1],0
  188.     jne    find_argv0
  189. found_argv0:
  190.     mov    word ptr [_pgmptr],si
  191.     mov    word ptr [_pgmptr+2],ds
  192.     xchg    ax,si        ; restore SI to [_acmdln]
  193.     test    byte ptr ds:[si],-1
  194.     jnz    store_cmdstart
  195.     xchg    ax,si        ; use PgmPtr instead of ArgPtr
  196. store_cmdstart:
  197.     mov    [cmdstart],si
  198.  
  199.     xor    dx,dx        ; Start with zero bytes
  200.     mov    di,1        ; Start with one arguments
  201. count_argv0:
  202.     lodsb
  203.     inc    dx        ; count each byte in argv[0]
  204.     or    al,al        ; including the terminator
  205.     jnz    count_argv0
  206. ;*
  207. ;*    Count the command line arguments
  208. ;*
  209. ;*        ... previous environment strings ...
  210. ;*        null byte    (end of last environment string)
  211. ;*        null byte    (end of environment)
  212. ;*        program name string
  213. ;*        null byte
  214. ;*    DS:SI ==> raw command line string
  215. ;*        null byte
  216. ;*        null byte
  217. ;*
  218. ;*    DI    will count the number of arguments
  219. ;*
  220. ;*    DX    will count the number of bytes needed to
  221. ;*        store the arguments themselves, incl. final nulls
  222. ;*
  223. ;*
  224. ;*    Count the command tail arguments
  225. ;*
  226. ;
  227. ;    DI will count the number of arguments
  228. ;    DX will count the number of bytes needed for the arguments
  229. ;        (not including the null terminators)
  230. ;
  231. arg100:
  232. arg110:
  233.     lodsb
  234.     cmp    al,C_BLANK
  235.     je    arg110
  236.     cmp    al,C_TAB
  237.     je    arg110
  238.  
  239.     DELIM
  240.     je    arg400
  241.  
  242.     inc    di        ; Another argument
  243. ;
  244. ; Parse an argument
  245. ;
  246. arg200:
  247.     dec    si        ; back up to reload character
  248. arg210:
  249.     lodsb
  250.  
  251.     cmp    al,C_BLANK
  252.     je    arg100
  253.     cmp    al,C_TAB
  254.     je    arg100        ; white space terminates argument
  255.  
  256.     DELIM
  257.     je    arg400
  258.  
  259.     cmp    al,C_QUOTE
  260.     je    arg310
  261.  
  262.     cmp    al,C_BACKSLASH
  263.     je    arg220
  264.  
  265.     inc    dx
  266.     jmps    arg210
  267. ;
  268. ; Count backslashes
  269. ;
  270. arg220:
  271.     xor    cx,cx
  272. arg221:
  273.     inc    cx        ; CX counts the backslashes
  274.     lodsb
  275.     cmp    al,C_BACKSLASH
  276.     je    arg221
  277. ;
  278.     cmp    al,C_QUOTE
  279.     je    arg230
  280.  
  281.     add    dx,cx        ; not followed by `"' -- treat `\'s normally
  282.     jmp    arg200
  283. ;
  284. arg230:
  285.     mov    ax,cx
  286.     shr    cx,1
  287.     adc    dx,cx        ; add 1 for every pair of backslashes
  288.     test    al,1        ; plus 1 for the " if odd number of \
  289.     jnz    arg210        ; " was escaped with a \
  290.     jmps    arg310        ; " opens a quoted substring
  291. ;
  292. ; Enter a quoted string
  293. ;
  294. arg300:
  295.     dec    si        ; back up to reload character
  296. arg310:
  297.     lodsb
  298.  
  299.     DELIM
  300.     je    arg400
  301.  
  302.     cmp    al,C_QUOTE
  303.     je    arg210        ; end of quoted portion of string
  304.  
  305.     cmp    al,C_BACKSLASH
  306.     je    arg320
  307.  
  308.     inc    dx
  309.     jmp    arg310
  310. ;
  311. ; Count backslashes
  312. ;
  313. arg320:
  314.     xor    cx,cx
  315. arg321:
  316.     inc    cx        ; CX counts the backslashes
  317.     lodsb
  318.     cmp    al,C_BACKSLASH
  319.     je    arg321
  320. ;
  321.     cmp    al,C_QUOTE
  322.     je    arg330
  323.  
  324.     add    dx,cx        ; not followed by `"' -- treat `\'s normally
  325.     jmp    arg300
  326. ;
  327. arg330:
  328.     mov    ax,cx
  329.     shr    cx,1
  330.     adc    dx,cx        ; add 1 for every pair of backslashes
  331.     test    al,1        ; plus 1 for the " if odd number of \
  332.     jnz    arg310        ; " was escaped with a \
  333.     jmps    arg210        ; " closes a quoted substring
  334. ;
  335. ; Command line is fully parsed - compute number of bytes needed
  336. ;
  337. arg400:
  338. ;
  339. ;    Number of bytes needed =
  340. ;        Number of bytes used to make strings +
  341. ;        Number of bytes used to terminate strings +
  342. ;        sizeof(DATAPTR) * ( number of arguments + 1 )
  343. ;
  344. if  _SSNEDS
  345.     push    es
  346. else
  347.     push    ss
  348. endif ;_SSNEDS
  349.     pop    ds        ; Restore DS = DGROUP
  350.     assumes ds,data
  351.  
  352.     mov    __argc,di    ; Store number of arguments
  353.  
  354.     add    dx,di        ; add in terminator bytes
  355. ifdef    WILDCARD
  356.     add    dx,di        ; add in Wildcard flag bytes
  357. endif
  358.     inc    di        ; add one for NULL pointer
  359.     shl    di,1
  360. if    sizeD
  361.     shl    di,1
  362. endif
  363.     mov    ax,di
  364.     add    ax,dx        ; add space for pointers to space for chars
  365.  
  366.     inc    ax
  367.     and    al,not 1    ; Round up to an even number of bytes
  368. ;
  369. ;    Allocate space on the heap (or the stack in non-DLL)
  370. ;
  371. ;    AX is the total number of bytes needed for strings and pointers
  372. ;    DI is the number of bytes needed for the pointers
  373. ;
  374.     call    _stdalloc    ; dx:ax = allocated memory
  375.     jnc    args_ok
  376. arg_error:
  377.     mov    ax,_RT_SPACEARG ; Out of heap space
  378.     jmp    _amsg_exit
  379.  
  380. args_ok:
  381.     mov    word ptr (__argv),ax    ; offset
  382. if    sizeD
  383.     mov    word ptr (__argv+2),dx    ; segment
  384. endif
  385. ;
  386. ;    Copy argument strings and addresses onto heap/stack
  387. ;        Address table is on the top, strings below that
  388. ;
  389. if  _SSNEDS
  390.     push    ds        ; save two copies of DGROUP for later
  391.     push    ds
  392. endif ;_SSNEDS
  393.  
  394.     mov    bx,ax
  395.     add    di,ax
  396.  
  397.     mov    es,dx        ; ES:DI is where the string copies will go
  398.     assumes es,data
  399. ;
  400. ;    DS:SI    points to the argv[0]
  401. ;
  402. ;    ES:BX    points to where argv[0],argv[1],argv[2],... go
  403. ;    ES:DI    points to where *argv[0],*argv[1],*argv[2],... go
  404. ; For wildcard version only (DX initialized below):
  405. ;    ES:DX    points to the wildcard flag character (prepended to argument)
  406. ;        during the creation of each argument
  407. ;
  408.  
  409.     mov    es:[bx],di    ; argv[i] - offset part
  410. if    sizeD
  411.     mov    es:[bx+2],es    ; argv[i] - segment part
  412.     add    bx,4
  413. else
  414.     inc    bx
  415.     inc    bx
  416. endif
  417.  
  418.     mov    si,cmdstart    ; Get pointer to argv[0]
  419.     mov    ds,_aenvseg
  420.     assumes ds,nothing
  421.  
  422. ifdef    WILDCARD
  423.     movsb
  424.     dec    si        ; copy first character as quote flag
  425. endif
  426.  
  427. copy_argv0:
  428.     lodsb
  429.     stosb
  430.     or    al,al
  431.     jnz    copy_argv0
  432. ;
  433. ;    DS:SI    points to the raw command tail string
  434. ;
  435.  
  436.     jmps    arg510
  437. ;
  438. ;    Skip blanks
  439. ;
  440. arg500:
  441.     xor    ax,ax
  442.     stosb
  443. arg510:
  444.     lodsb
  445.     cmp    al,C_BLANK
  446.     je    arg510
  447.     cmp    al,C_TAB
  448.     je    arg510
  449.  
  450.     DELIM
  451. ifdef    WILDCARD
  452. if    sizeD
  453.     lje    arg810
  454. else
  455.     je    arg810
  456. endif
  457. else
  458.     je    arg810
  459. endif
  460.  
  461.     mov    es:[bx],di
  462. if    sizeD
  463.     mov    es:[bx+2],es
  464.     add    bx,4
  465. else
  466.     inc    bx
  467.     inc    bx
  468. endif
  469.  
  470. ifdef    WILDCARD
  471.     mov    dx,di
  472.     stosb            ; initialize wildcard flag
  473. endif
  474. ;
  475. ;
  476. ; Parse an argument
  477. ;
  478. arg600:
  479.     dec    si        ; back up to reload character
  480. arg610:
  481.     lodsb
  482.  
  483.     cmp    al,C_BLANK
  484.     je    arg500
  485.     cmp    al,C_TAB
  486.     je    arg500        ; white space terminates argument
  487.  
  488.     DELIM
  489.     je    arg800
  490.  
  491.     cmp    al,C_QUOTE
  492.     je    arg710x
  493.  
  494.     cmp    al,C_BACKSLASH
  495.     je    arg620
  496.  
  497.     stosb
  498.     jmps    arg610
  499. ;
  500. ; Count backslashes
  501. ;
  502. arg620:
  503.     xor    cx,cx
  504. arg621:
  505.     inc    cx        ; CX counts the backslashes
  506.     lodsb
  507.     cmp    al,C_BACKSLASH
  508.     je    arg621
  509. ;
  510.     cmp    al,C_QUOTE
  511.     je    arg630
  512.  
  513.     mov    al,C_BACKSLASH
  514.     rep    stosb        ; not followed by `"' -- treat `\'s normally
  515.     jmp    arg600
  516. ;
  517. arg630:
  518.     mov    al,C_BACKSLASH
  519.     shr    cx,1
  520.     rep    stosb
  521.     jnc    arg710x     ; " opens a quoted substring
  522.     mov    al,C_QUOTE
  523.     stosb
  524.     jmp    arg610        ; " was escaped with a \
  525. ;
  526. ; Enter a quoted string
  527. ;
  528. ifdef    WILDCARD
  529. arg710x:
  530.     inc    si        ; undoes the "DEC SI" between arg700 and arg710
  531. endif
  532.  
  533. arg700x:
  534.  
  535. ifdef    WILDCARD
  536.     xchg    dx,di        ; set the wildcard flag character to `"'
  537.     mov    al,C_QUOTE
  538.     stosb
  539.     dec    di
  540.     xchg    dx,di
  541. endif
  542.  
  543. arg700:
  544.     dec    si        ; back up to reload character
  545.  
  546. ifndef    WILDCARD
  547. arg710x:
  548. endif
  549.  
  550. arg710:
  551.     lodsb
  552.  
  553.     DELIM
  554.     je    arg800
  555.  
  556.     cmp    al,C_QUOTE
  557.     je    arg610        ; end of quoted portion of string
  558.  
  559.     cmp    al,C_BACKSLASH
  560.     je    arg720
  561.  
  562.     stosb
  563.     jmp    arg710
  564. ;
  565. ; Count backslashes
  566. ;
  567. arg720:
  568.     xor    cx,cx
  569. arg721:
  570.     inc    cx        ; CX counts the backslashes
  571.     lodsb
  572.     cmp    al,C_BACKSLASH
  573.     je    arg721
  574. ;
  575.     cmp    al,C_QUOTE
  576.     je    arg730
  577.  
  578.     mov    al,C_BACKSLASH
  579.     rep    stosb        ; not followed by `"' -- treat `\'s normally
  580.     jmp    arg700x
  581. ;
  582. arg730:
  583.     mov    al,C_BACKSLASH
  584.     shr    cx,1
  585.     rep    stosb        ; store 1 for every pair of backslashes
  586.     jnc    arg610        ; " closes a quoted substring
  587.     mov    al,C_QUOTE    ; " was escaped with a \
  588.     stosb
  589.     jmps    arg710x
  590. ;
  591. ; Terminate last argument string, terminate list of argument pointers
  592. ;
  593. arg800:
  594.     xor    ax,ax
  595.     stosb            ; null-terminate final argument
  596. arg810:
  597.     mov    word ptr es:[bx],0 ; add null pointer to __argv[]
  598. if    sizeD
  599.     mov    word ptr es:[bx+2],0
  600. endif
  601.  
  602. if  _SSNEDS
  603.     pop    es        ; ES = DS = DGROUP
  604.     pop    ds
  605. else
  606.     push    ss
  607.     pop    ds        ; restore ds
  608. endif ;_SSNEDS
  609.  
  610.  
  611.     assumes ds,data
  612.  
  613. ifndef    WILDCARD
  614.  
  615.   if  _SSNEDS
  616.     if sizeC
  617.     retf            ; THE END
  618.     else
  619.     retn            ; THE END
  620.     endif
  621.   else    ;_SSNEDS
  622.     jmp    [retadr]    ; THE END
  623.   endif ;_SSNEDS
  624.  
  625. else  ; WILDCARD
  626.  
  627.     call    _cwild
  628.     test    ax,ax
  629.     jnz    to_arg_error
  630.   if  _SSNEDS
  631.     if sizeC
  632.     retf            ; THE END
  633.     else
  634.     retn            ; THE END
  635.     endif
  636.   else ; _SSNEDS
  637.     jmp    [retadr]    ; THE END
  638.   endif ;_SSNEDS
  639.  
  640. to_arg_error:
  641.     jmp    arg_error
  642.  
  643. page
  644. ;***
  645. ;_find(pattern) - find matching filename
  646. ;
  647. ;Purpose:
  648. ;    if argument is non-null, do a DosFindFirst on that pattern
  649. ;    otherwise do a DosFindNext call.  Return matching filename
  650. ;    or NULL if no more matches.
  651. ;
  652. ;    char *_find(pattern)
  653. ;           char *pattern;
  654. ;    {
  655. ;    static struct  FileFindBuf     findbuf;
  656. ;    static unsigned findhandle=1;
  657. ;               unsigned findcount=1;
  658. ;               int rc;
  659. ;
  660. ;           if(pattern)
  661. ;               rc = DOSFINDFIRST((char far *) pattern,
  662. ;                   (unsigned far *) &findhandle, A_D,
  663. ;                   (struct FileFindBuf far *) &findbuf, sizeof(findbuf),
  664. ;                   (unsigned far *) &findcount, 0L);
  665. ;           else
  666. ;               rc = DOSFINDNEXT(findhandle,
  667. ;                   (struct FileFindBuf far *) &findbuf, sizeof(findbuf),
  668. ;                   (unsigned far *) &findcount);
  669. ;
  670. ;           return(rc ? NULL : findbuf.file_name);
  671. ;    }
  672. ;
  673. ;Entry:
  674. ;    pattern = pointer to pattern or NULL
  675. ;          (NULL means find next matching filename)
  676. ;
  677. ;Exit:
  678. ;    AX (or DX:AX) = pointer to matching file name
  679. ;            or NULL if no more matches.
  680. ;
  681. ;Uses:
  682. ;
  683. ;Exceptions:
  684. ;
  685. ;*******************************************************************************
  686.  
  687. cProc    _find,<PUBLIC>,<>
  688.     parmDP    pattern
  689. ;    localW    findcount
  690. findcount equ    (word ptr [bp-2])
  691. cBegin
  692.     mov    ax,1
  693.     push    ax        ; mov    [findcount],1
  694.     mov    bx,dataOFFSET findbuf
  695.     mov    dx,size findbuf
  696.     lea    ax,findcount
  697. ;
  698. ;    DS:BX = &findbuf
  699. ;    DX = sizeof(findbuf)
  700. ;    SS:AX = &findcount
  701. ;    CX = FP_OFF(pattern)
  702. ;
  703. if    sizeD
  704.     les    cx,pattern
  705.     cmp    word ptr [pattern+2],0
  706.     jz    find_next
  707. else
  708.     mov    cx,pattern
  709.     jcxz    find_next
  710. endif
  711. ;
  712. ;    Make first call to DOSFINDFIRST
  713. ;
  714. if    sizeD
  715.     push    es
  716. else
  717.     push    ds
  718. endif
  719.     push    cx        ; (char far *) pattern
  720.     mov    cx,dataOFFSET findhandle
  721.     mov    [findhandle],1    ; always use handle 1
  722.     push    ds
  723.     push    cx        ; (unsigned far *) & findhandle
  724.     mov    cx,A_D
  725.     push    cx        ; match attribute: normal files + directories
  726.     push    ds
  727.     push    bx        ; (struct FileFindBuf far *) &findbuf
  728.     push    dx        ; sizeof(findbuf)
  729.     push    ss
  730.     push    ax        ; (unsigned far *) &findcount
  731.     xor    ax,ax
  732.     push    ax
  733.     push    ax        ; 0L (reserved)
  734.     call    DOSFINDFIRST
  735.     jmp    short    check_rc
  736. ;
  737. ;    get next match
  738. ;
  739. find_next:
  740.     push    [findhandle]    ; findhandle
  741.     push    ds
  742.     push    bx        ; (struct FileFindBuf far *) &findbuf
  743.     push    dx        ; sizeof(findbuf)
  744.     push    ss
  745.     push    ax
  746.     call    DOSFINDNEXT
  747. ;
  748. check_rc:
  749.     add    bx,dataOFFSET file_name ; BX = findbuf.file_name
  750. if    sizeD
  751.     mov    dx,ds
  752. endif
  753.     test    ax,ax        ; check for error in system call
  754.     xchg    ax,bx        ; return findbuf.file_name if successful
  755.     jz    rc_zero
  756. ;
  757.     xor    ax,ax        ; return NULL for error
  758. if    sizeD
  759.     cwd
  760. endif
  761. rc_zero:
  762.  
  763. cEnd
  764.  
  765. endif                ;    WILDCARD
  766.  
  767. sEnd    code
  768.  
  769.     end
  770.