home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / mslang / params / params.asm next >
Encoding:
Assembly Source File  |  1993-09-30  |  7.8 KB  |  204 lines

  1. .model small
  2.  
  3. .data
  4.    PUBLIC PSPSeg
  5.    firstScan db 1
  6.    PSPSeg    dw 0
  7.    QUOTE EQU '"'   ; if this is EQU 0, quoted strings will not be 
  8.                    ; recognized as one paramter, if they contain
  9.                    ; whitespace (blanks)
  10. .stack 100h
  11.  
  12. .code
  13.  
  14. ;*******************************************************************
  15. ;  void ScanCommands( void );
  16. ;  Parses the command line into parameters, terminating each with
  17. ;  a zero byte and the whole line with another zero byte.
  18. ;  Separators for parameters are all characters <= ' '. If the QUOTE 
  19. ;  symbol is <> 0, a string enclosed in QUOTEs will be treated as one 
  20. ;  parameter, even if it contains whitespace. There may be other non-
  21. ;  blank characters before and after the quote, which will be counted
  22. ;  as belonging to the same parameter.
  23. ;  Will set the firstScan variable to 0. Assumes ds=@data, preserves
  24. ;  all registers.
  25. ;*******************************************************************
  26. ScanCommands PROC USES ax bx cx dx ds
  27.      mov firstScan, 0      ; set flag to false 
  28.      ; set up ds:bx to point to the command line, cl with the length
  29.      mov  ds, PSPSeg
  30. ASSUME ds:nothing
  31.      mov  bx, 80h
  32.      mov  cl, byte ptr [bx]
  33.      inc  bx
  34.      or   cl, cl
  35.      jz   end_of_line
  36.  
  37.      ; The following scanning loop has two parts. First we look for
  38.      ; a non-whitespace char as start of a parameter, then for its end.
  39.      ; cl is tested for end of commandline conditions
  40.      ; Throughout this loop, ch holds the QUOTE character, al the
  41.      ; current character and ah the terminator to skip or find.
  42.  
  43.      mov  ch, QUOTE        ; load working registers
  44.      mov  ah, ' '          ; terminator is whitespace first
  45.      ; find start of next param
  46. find_new_param:
  47.      mov  al, [bx]         ; get next character
  48.      cmp  al, ah           ; compare to current terminator (' ' here)
  49.      ja   param_start      ; if it is a whitespace
  50. find_1:
  51.      inc  bx               ; point to next character
  52.      dec  cl               ; dec character counter
  53.      jz   end_of_line      ; if it is zero, end of line reached
  54.      jmp  short find_new_param ; else test next char
  55.      ; found param, seek for its end
  56. param_start:
  57.      cmp  al, ch           ; is char the quote char?
  58.      jne  no_quote         ; if yes, 
  59.      cmp  al, ah           ; are we currently looking for one as terminator?
  60.      jne  starting_quote   ; if yes
  61.      mov  ah, ' '          ; reset terminator to blank, we found the end
  62.                            ; of a quoted string
  63.      jmp  short next_char
  64. starting_quote:            ; else make the quote the terminator IF it is
  65.                            ; not zero!
  66.      or   ch, ch
  67.      jz   find_1           ; hey! we have a zero-terminated string here,
  68.                            ; a ready-made parameter, so seek the next
  69.      mov  ah, ch           ; else look for the quote next
  70.      jmp  short next_char
  71. no_quote:
  72.      cmp  al, ah           ; is this character a whitespace?
  73.      ja   next_char        ; if yes
  74.      cmp  ah, ch           ; are we looking for a quote as terminator?
  75.      je   next_char        ; if not
  76.      mov  byte ptr [bx],0  ; make current character a zero char
  77.      jmp  find_1           ; and go looking for the next parameters start
  78.  
  79. next_char:
  80.      inc  bx               ; point to next character
  81.      dec  cl               ; dec character counter
  82.      jz   end_of_line      ; if it is zero, end of line reached
  83.      mov  al, [bx]         ; else load the next character
  84.      jmp  short param_start; and go test it
  85.  
  86. end_of_line:
  87.      cmp  bx, 100h         ; are we still inside the PSP?
  88.      jnb  scan_done        ; if yes
  89.      mov  byte ptr [bx], 0 ; add an additional zero byte
  90.  
  91. scan_done:
  92.      ret
  93. ASSUME ds:@data
  94.  
  95. ScanCommands ENDP
  96.  
  97. ;*******************************************************************
  98. ;   int ParamCount( void );
  99. ;
  100. ;   ParamCount returns the number of parameters on the command line
  101. ;   in AX. Keeps all other registers unchanged.
  102. ;   On the first run, ParamCount will parse the command line and 
  103. ;   convert each parameter to a zero-terminated string.
  104. ;
  105. ;   Assumes ds is pointing to @data
  106. ;*******************************************************************
  107. ParamCount PROC PUBLIC USES si cx ds
  108.      test firstScan, 0FFh  ; flag <> 0?
  109.      jz   @F
  110.      call ScanCommands     ; if not, parse the commandline
  111. @@:
  112.      ; count the zero bytes in the command tail, this now gives
  113.      ; the number of parameters
  114.      mov  ds, PSPSeg ; point ds:si at length byte of command tail
  115. ASSUME ds:nothing
  116.      mov  si, 80h
  117.      mov  cl, [si]
  118.      sub  ch, ch     ; cx has length of command tail
  119.      inc  si         ; ds:si points to start of command tail
  120.      sub  ax, ax     ; use ax to hold count
  121.      jcxz count_done
  122. count_loop:
  123.      cmp  byte ptr [si], 0 ; is current char a zero byte?
  124.      jne  @F               ; if yes
  125.      inc  ax               ; count it
  126. @@:
  127.      inc  si               ; next char
  128.      dec  cx
  129.      jnz  count_loop       ; loop if not done
  130.      ; slight problem here, we will not get to the zero terminating
  131.      ; the last parameter 'cause its not included in the character count
  132.      ; just test if the last character tested was a zero, if not, assume
  133.      ; an additonal parameter
  134.      dec  si
  135.      cmp  byte ptr [si], 0
  136.      je   count_done
  137.      inc  ax
  138. count_done:
  139.      ret 
  140. ASSUME ds:@data
  141. ParamCount ENDP
  142.  
  143. ;*******************************************************************
  144. ;   char far *ParamStr( int n );
  145. ;
  146. ;   ParamStr returns a far pointer to the n-th parameter on the
  147. ;   command line in dx:ax. Count starts at 1!
  148. ;   Uses register calling convention! n is expected in AX on entry.
  149. ;
  150. ;   Assumes ds is pointing to @data. Leaves all registers except
  151. ;   dx and ax intact.
  152. ;*******************************************************************
  153. ParamStr PROC PUBLIC USES bx cx ds
  154.      test firstScan, 0FFh  ; has command line be parsed yet?
  155.      jz   @F
  156.      call ScanCommands     ; if not, parse it now
  157. @@:
  158.      mov  cx, ax     ; cx has index (offset from 1)
  159.      mov  ds, PSPSeg ; point ds:bx at length byte of command tail
  160. ASSUME ds:nothing
  161.      mov  bx, 80h
  162.      mov  al, [bx]   ; use length value in al as a guard for overruns
  163.                      ; (index given > ParamCount)
  164.      inc  bx         ; point ds:bx at first char
  165.      jcxz @F         ; index 0 is an error but is treated as 1 here
  166.      dec  cx         ; convert index to number of zero-bytes to count
  167. @@:
  168.      jcxz found_param; if cx=0, index was 1, needs no search
  169.  
  170.      ; now search thru the command line, counting zero bytes as proxy
  171.      ; for a parameter
  172. find_loop:
  173.      cmp  byte ptr [bx], 0  ; is this the end of a param?
  174.      jne  @F                ; if yes
  175.      dec  cx                ; reduce count
  176. @@:     
  177.      inc  bx                ; next character
  178.      dec  al                ; dec guard value
  179.      jz   overrun           ; if it is now zero, we have reached the end
  180.                             ;   of the command line
  181.      jcxz found_param       ; else if cx is zero, we are at the start
  182.                             ;   of the requested parameter
  183.      jmp short find_loop    ; else continue search
  184.  
  185. found_param:
  186.      ; ds:bx now points at the start of a parameter. It may contain
  187.      ; blanks at the start due to the parsing method. Skip over these.
  188.      ; A non-blank character is guaranteed in the parameter.
  189. skip_blanks:
  190.      cmp byte ptr [bx], ' ' ; is this a whitespace character?
  191.      ja  @F                 ; if not, done
  192.      inc bx                 ; else skip it
  193.      jmp short skip_blanks  ; and test again
  194. @@:
  195. overrun:                    ; if overrun, bx will point to a zero-byte
  196.      mov dx, ds             ; set up result in dx:ax
  197.      mov ax, bx
  198.      ret
  199. ASSUME ds:@data
  200. ParamStr ENDP
  201.  
  202. END
  203.