home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / PCMAG / VOL7N22.ARC / PP722.ARC / ARGV.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-10-06  |  4.9 KB  |  126 lines

  1. ;----------------------------------------------------------------------
  2. ; ARGV.ASM:     Return address and length of specified
  3. ;               command line argument or fully qualified
  4. ;               program name.  Treats blanks and tabs
  5. ;               as whitespace.
  6. ;
  7. ; Copyright (c) 1988 Ziff Communications Co.
  8. ; PC Magazine * Ray Duncan * 12-27-88
  9. ;
  10. ; Call with:    AX    = argument number (0 based)
  11. ;
  12. ; Returns:      ES:BX = argument address
  13. ;               AX    = argument length (0=no argument)
  14. ;
  15. ; Uses:         nothing (other registers preserved)
  16. ;
  17. ; Note: if called with AX=0 (argv[0]), returns ES:BX
  18. ; pointing to fully qualified program name in environment
  19. ; block and AX=length.
  20. ;----------------------------------------------------------------------
  21.         .286
  22.  
  23. tab     equ     09h             ; ASCII tab
  24. blank   equ     20h             ; ASCII space character
  25.  
  26.         extrn   DosGetEnv:far
  27.  
  28. _TEXT   segment word public 'CODE'
  29.         assume  cs:_TEXT
  30.  
  31.         public  argv            ; make ARGV available to Linker
  32.                                 ; local variables...
  33. envseg  equ     [bp-2]          ; environment segment
  34. cmdoffs equ     [bp-4]          ; command line offset
  35.  
  36. argv    proc    near
  37.  
  38.         enter   4,0             ; make room for local variables
  39.         push    cx              ; save original CX and DI
  40.         push    di
  41.  
  42.         push    ax              ; save argument number
  43.  
  44.         push    ss              ; get selector for environment
  45.         lea     ax,envseg       ; and offset of command line
  46.         push    ax
  47.         push    ss
  48.         lea     ax,cmdoffs
  49.         push    ax
  50.         call    DosGetEnv       ; transfer to OS/2
  51.         or      ax,ax           ; test operation status
  52.         pop     ax              ; restore argument number
  53.         jnz     argv7           ; jump if DosGetEnv failed
  54.  
  55.         mov     es,envseg       ; set ES:BX = command line
  56.         mov     bx,cmdoffs
  57.  
  58.         or      ax,ax           ; is requested argument=0?
  59.         jz      argv8           ; yes, jump to get program name
  60.  
  61. argv0:  inc     bx              ; scan off first field
  62.         cmp     byte ptr es:[bx],0
  63.         jne     argv0
  64.  
  65.         xor     ah,ah           ; initialize argument counter
  66.  
  67. argv1:  mov     cx,-1           ; set flag = outside argument
  68.  
  69. argv2:  inc     bx              ; point to next character
  70.         cmp     byte ptr es:[bx],0
  71.         je      argv7           ; exit if null byte
  72.         cmp     byte ptr es:[bx],blank
  73.         je      argv1           ; outside argument if ASCII blank
  74.         cmp     byte ptr es:[bx],tab
  75.         je      argv1           ; outside argument if ASCII tab
  76.                                 ; if not blank or tab...
  77.         jcxz    argv2           ; jump if already inside argument
  78.  
  79.         inc     ah              ; else count arguments found
  80.         cmp     ah,al           ; is this the one we're looking for?
  81.         je      argv4           ; yes, go find its length
  82.         not     cx              ; no, set flag = inside argument
  83.         jmp     argv2           ; and look at next character
  84. argv4:                          ; found desired argument, now
  85.                                 ; determine its length...
  86.         mov     ax,bx           ; save param. starting address
  87.  
  88. argv5:  inc     bx              ; point to next character
  89.         cmp     byte ptr es:[bx],0
  90.         je      argv6           ; found end if null byte
  91.         cmp     byte ptr es:[bx],blank
  92.         je      argv6           ; found end if ASCII blank
  93.         cmp     byte ptr es:[bx],tab
  94.         jne     argv5           ; found end if ASCII tab
  95.  
  96. argv6:  xchg    bx,ax           ; set ES:BX = argument address
  97.         sub     ax,bx           ; and AX = argument length
  98.         jmp     argvx           ; return to caller
  99.  
  100. argv7:  xor     ax,ax           ; set AX = 0, argument not found
  101.         jmp     argvx           ; return to caller
  102. argv8:                          ; special handling for argv=0
  103.         xor     di,di           ; find the program name by
  104.         xor     al,al           ; first skipping over all the
  105.         mov     cx,-1           ; environment variables...
  106.         cld
  107. argv9:  repne scasb             ; scan for double null (can't use
  108.         scasb                   ; (SCASW since might be odd addr.)
  109.         jne     argv9           ; loop if it was a single null
  110.         mov     bx,di           ; save program name address
  111.         mov     cx,-1           ; now find its length...
  112.         repne scasb             ; scan for another null byte
  113.         not     cx              ; convert CX to length
  114.         dec     cx
  115.         mov     ax,cx           ; return length in AX
  116. argvx:                          ; common exit point
  117.         pop     di              ; restore original CX and DI
  118.         pop     cx
  119.         leave                   ; discard stack frame
  120.         ret                     ; return to caller
  121.  
  122. argv    endp
  123.  
  124. _TEXT   ends
  125.         end
  126.