1 ; SCCSID = @(#)parse.asm 1.2 85/07/23
2 TITLE PARSE
- Parsing system calls for
MS-DOS
5 ; System calls for parsing command lines
7 ; $PARSE_FILE_DESCRIPTOR
9 ; Modification history:
11 ; Created: ARR 30 March 1983
12 ; EE PathParse 10 Sept 1983
17 ; get the appropriate segment definitions
21 CODE SEGMENT BYTE PUBLIC 'CODE'
22 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
34 BREAK <$Parse_File_Descriptor
-- Parse an arbitrary string
into an FCB
>
37 ; DS:SI Points to a command line
38 ; ES:DI Points to an empty FCB
39 ; Bit 0 of AL = 1 At most one leading separator scanned off
40 ; = 0 Parse stops if separator encountered
41 ; Bit 1 of AL = 1 If drive field blank in command line - leave FCB
42 ; = 0 " " " " " " - put 0 in FCB
43 ; Bit 2 of AL = 1 If filename field blank - leave FCB
44 ; = 0 " " " - put blanks in FCB
45 ; Bit 3 of AL = 1 If extension field blank - leave FCB
46 ; = 0 " " " - put blanks in FCB
48 ; Parse command line into FCB
50 ; AL = 1 if '*' or '?' in filename or extension, 0 otherwise
51 ; DS:SI points to first character after filename
53 procedure $PARSE_FILE_DESCRIPTOR
,NEAR
54 ASSUME
DS:NOTHING
,ES:NOTHING
61 EndProc $PARSE_FILE_DESCRIPTOR
65 BREAK <$PathParse
- Parse a string
>
67 ;------------------------------------------------------------------------------
69 ; Parse is a string parser. It copies the next token into a buffer, updates
70 ; the string pointer, and builds a flag word which describes the token.
73 ; DS:SI - Points to the beginning of the string to be parsed
74 ; ES:DI - Points to the buffer which will hold the new token
78 ; DS:SI - String pointer updated to point past the token just found
79 ; All other registers are unchanged.
81 ; All of the isXXXX procedures called by the main routine test a character
82 ; to see if it is of a particular type. If it is, they store the character
83 ; and return with the ZF set.
86 ; isswit issep ispchr ispsep isinval isdot ischrnull dirdot pasep
89 ; INTERNAL REGISTER USAGE
90 ; AH - FF/00 to indicate whether a path token can terminated with a
92 ; AL - Used with lodsb/stosb to transfer and test chars from DS:SI
93 ; BX - Holds flag word
94 ; CX - Used with loop/rep and as a work var
95 ; DX - Used to test the length of names and extensions
98 ; The memory pointed to by DI has the next token copied into it.
101 ; It is the caller's responsibility to make sure DS:SI does not point
102 ; to a null string. If it does, SI is incremented, a null byte is
103 ; stored at ES:DI, and the routine returns.
105 ;------------------------------------------------------------------------------
106 ParseClassMask equ
1110000000000000b ; Token class mask
107 ParseSwitch equ
1000000000000000b ; Switch class
108 ParseSeparators equ
0100000000000000b ; Separator class
109 ParsePathName equ
0010000000000000b ; Path class
110 ParsePathNameData equ
0000000000001111b ; Path token data mask
111 ParsePathSynErr equ
0000000000000001b ; Path has syntax error
112 ParsePathWild equ
0000000000000010b ; Path has wildcards
113 ParsePathSeparators equ
0000000000000100b ; Path has pseparators
114 ParseInvalidDrive equ
0000000000001000b ; Path has invald drive
117 ; Sepchars is a string containing all of the token separator characters
118 ; and is used to test for separators.
121 Public PRS001S
,PRS001E
123 sepchrs db 9,10,13,' ','+',',',';','=' ; tab cr lf sp + , ; =
128 Procedure $PathParse
,NEAR
129 assume
ds:nothing
,es:nothing
130 xor ah,ah ; initialize registers and flags
133 lodsb ; used the first byte of the token to
134 call isswit
; determine its type and call the routine to
149 inval: or bx,ParsePathName
; an invalid character/path token
150 or bx,ParsePathSynErr
; was found, set the appropriate
151 call issep
; flag bits and parse the rest of
152 jne icont
; the token
157 switch: mov bx,ParseSwitch
; found a switch, set flag and parse
158 jmp ptosep
; the rest of it
160 separ: mov bx,ParseSeparators
; found separator, set flag and parse
161 seloop: lodsb ; everything up to the next non
162 call issep
; separator character
166 path: or bx,ParsePathName
; found path, set flag
167 mov cx,8 ; set up to parse a file name
169 call pasep
; if the token began with a path
170 jne pcont1
; separator or . call rcont which
171 not ah ; handles checksfor . and ..
178 pcont2: cmp al,'A' ; if token may start with a drive
179 jge drive
; designator, go to drive. otherwise
180 jmp name1
; parse a file name.
182 drive: cmp byte ptr [si],':' ; if there is a drive designator, parse
183 jne name1
; and verify it. otherwise parse a file
194 dcont2: or bx,ParseInvalidDrive
201 repeat: mov al,byte ptr [si-2] ; repeat and rcont test for //, \\, .,
202 call pasep
; and .. and repeatedly calls name
203 jne rcont
; and ext until a path token has
204 inc si ; been completely parsed.
214 name: lodsb ; parse and verify a file name
230 ext: mov cx,3 ; parse and verify a file extension
242 dcheck: call ispsep
; do the checks need to make sure
243 je repeat ; a file name or extension ended
244 call issep
; correctly and checks to see if
245 je bkboth
; we're done
250 ptosep: lodsb ; parse everything to the next separator
257 or bx,ParsePathSynErr
261 bkboth: dec di ; clean up when the end of the token
262 bksi: dec si ; is found, stick a terminating null
263 done: xor al,al ; byte at the end of buf, and exit
266 invoke Get_user_stack
273 ; Is current character the beginning of a switch?
283 ; Is the current character a separator?
292 mov di,offset dosgroup
:sepchrs
303 ; Is the current character a path character? If it is a wildcard char too,
334 pcwild: or bx,ParsePathWild
341 ; Is the current character a path separator? If so, set that flag after
348 or bx,ParsePathSeparators
354 ; Set ZF if the character in AL is a path separator.
366 ; Is the current character invalid?
391 ; Is the current character a dot?
401 ; Is the current character null? If so, update SI for exiting.
412 ; Check for . and .. Before returning, CF and ZF are set to indicate whether
413 ; the token is invalid (found . or .. followed by an invalid char - CF on),
414 ; we're done (found . or .. followed by null or a separator - ZF on), or the
415 ; token continues (. and .. not found or found and followed by a path
416 ; separator - both flags off).
419 cmp byte ptr [si], '.'
423 cmp byte ptr [si],'.'
434 direti: stc ; Invalid return
438 diretd: cmp al,al ; Done return
440 diretc: cmp ah,1 ; Continue return