]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/PARSE.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / PARSE.ASM
1 ; SCCSID = @(#)parse.asm 1.2 85/07/23
2 TITLE PARSE - Parsing system calls for MS-DOS
3 NAME PARSE
4 ;
5 ; System calls for parsing command lines
6 ;
7 ; $PARSE_FILE_DESCRIPTOR
8 ;
9 ; Modification history:
10 ;
11 ; Created: ARR 30 March 1983
12 ; EE PathParse 10 Sept 1983
13 ;
14
15 .xlist
16 ;
17 ; get the appropriate segment definitions
18 ;
19 include dosseg.asm
20
21 CODE SEGMENT BYTE PUBLIC 'CODE'
22 ASSUME SS:DOSGROUP,CS:DOSGROUP
23
24 .xcref
25 INCLUDE DOSSYM.INC
26 INCLUDE DEVSYM.INC
27 .cref
28 .list
29
30 BOGUS =FALSE
31 .lall
32 I_Need chSwitch,BYTE
33
34 BREAK <$Parse_File_Descriptor -- Parse an arbitrary string into an FCB>
35
36 ; Inputs:
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
47 ; Function:
48 ; Parse command line into FCB
49 ; Returns:
50 ; AL = 1 if '*' or '?' in filename or extension, 0 otherwise
51 ; DS:SI points to first character after filename
52
53 procedure $PARSE_FILE_DESCRIPTOR,NEAR
54 ASSUME DS:NOTHING,ES:NOTHING
55
56 invoke MAKEFCB
57 PUSH SI
58 invoke get_user_stack
59 POP [SI.user_SI]
60 return
61 EndProc $PARSE_FILE_DESCRIPTOR
62
63
64 IF BOGUS
65 BREAK <$PathParse - Parse a string>
66
67 ;------------------------------------------------------------------------------
68 ;
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.
71 ;
72 ; ENTRY
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
75 ;
76 ; EXIT
77 ; AX - Flag word
78 ; DS:SI - String pointer updated to point past the token just found
79 ; All other registers are unchanged.
80 ;
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.
84 ;
85 ; CALLS
86 ; isswit issep ispchr ispsep isinval isdot ischrnull dirdot pasep
87 ;
88 ;
89 ; INTERNAL REGISTER USAGE
90 ; AH - FF/00 to indicate whether a path token can terminated with a
91 ; slash or not.
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
96 ;
97 ; EFFECTS
98 ; The memory pointed to by DI has the next token copied into it.
99 ;
100 ; WARNINGS
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.
104 ;
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
115
116
117 ; Sepchars is a string containing all of the token separator characters
118 ; and is used to test for separators.
119
120 Table segment
121 Public PRS001S,PRS001E
122 PRS001S label byte
123 sepchrs db 9,10,13,' ','+',',',';','=' ; tab cr lf sp + , ; =
124 seplen equ $-sepchrs
125 PRS001E label byte
126 table ends
127
128 Procedure $PathParse,NEAR
129 assume ds:nothing,es:nothing
130 xor ah,ah ; initialize registers and flags
131 xor bx,bx
132 cld
133 lodsb ; used the first byte of the token to
134 call isswit ; determine its type and call the routine to
135 je switch ; parse it
136 call issep
137 je separ
138 call ispchr
139 je path
140 call ispsep
141 je path
142 call isdot
143 je path
144 call isinval
145 je inval
146 stosb
147 jmp done
148
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
153 dec di
154 icont: dec si
155 jmp ptosep
156
157 switch: mov bx,ParseSwitch ; found a switch, set flag and parse
158 jmp ptosep ; the rest of it
159
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
163 je seloop
164 jmp bksi
165
166 path: or bx,ParsePathName ; found path, set flag
167 mov cx,8 ; set up to parse a file name
168 mov dx,8
169 call pasep ; if the token began with a path
170 jne pcont1 ; separator or . call rcont which
171 not ah ; handles checksfor . and ..
172 jmp rcont
173 pcont1: cmp al,'.'
174 jne pcont2
175 dec si
176 dec di
177 jmp rcont
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.
181
182 drive: cmp byte ptr [si],':' ; if there is a drive designator, parse
183 jne name1 ; and verify it. otherwise parse a file
184 not ah ; name.
185 cmp al,'Z'
186 jle dcont1
187 sub al,' '
188 dcont1: sub al,'@'
189 invoke GetthisDrv
190 lodsb
191 stosb
192 jc dcont2
193 jmp dcont3
194 dcont2: or bx,ParseInvalidDrive
195 dcont3: dec cx
196 lodsb
197 call ispsep
198 je rcont
199 dec si
200
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.
205 jmp inval
206 rcont: call dirdot
207 je done
208 jc inval
209 mov cx,8
210 mov dx,8
211 jmp name
212
213 name1: dec cx
214 name: lodsb ; parse and verify a file name
215 call ispchr
216 jne ncheck
217 xor ah,ah
218 nloop: loop name
219 lodsb
220
221 ncheck: cmp ah,0
222 jne ncont
223 cmp cx,dx
224 jne ncont
225 jmp inval
226 ncont: call isdot
227 je ext
228 jmp dcheck
229
230 ext: mov cx,3 ; parse and verify a file extension
231 mov dx,3
232 extl: lodsb
233 call ispchr
234 jne echeck
235 eloop: loop extl
236 lodsb
237
238 echeck: cmp cx,dx
239 jne dcheck
240 jmp inval
241
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
246 call ischrnull
247 je done
248 jmp inval
249
250 ptosep: lodsb ; parse everything to the next separator
251 call issep
252 je bkboth
253 call ischrnull
254 je done
255 call isinval
256 jne ptcont
257 or bx,ParsePathSynErr
258 ptcont: stosb
259 jmp ptosep
260
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
264 stosb
265 push si
266 invoke Get_user_stack
267 mov [si].user_AX,bx
268 pop [si].user_SI
269 Transfer sys_ret_ok
270
271 Endproc $PathParse
272
273 ; Is current character the beginning of a switch?
274
275 isswit proc near
276 cmp al,[chSwitch]
277 jne swret
278 stosb
279 swret: ret
280 isswit endp
281
282
283 ; Is the current character a separator?
284
285 issep proc near
286 push cx
287 push di
288 push es
289 mov cx,cs
290 mov es,cx
291 mov cx,seplen
292 mov di,offset dosgroup:sepchrs
293 repne scasb
294 pop es
295 pop di
296 jne sepret
297 sepyes: stosb
298 sepret: pop cx
299 ret
300 issep endp
301
302
303 ; Is the current character a path character? If it is a wildcard char too,
304 ; set that flag.
305
306 ispchr proc near
307 cmp al,'!'
308 je pcyes
309 cmp al,'#'
310 jl pcret
311 cmp al,'*'
312 je pcwild
313 jl pcyes
314 cmp al,'-'
315 je pcyes
316 cmp al,'0'
317 jl pcret
318 cmp al,'9'
319 jle pcyes
320 cmp al,'?'
321 je pcwild
322 jl pcret
323 cmp al,'Z'
324 jle pcyes
325 cmp al,'^'
326 jl pcret
327 cmp al,'{'
328 jle pcyes
329 cmp al,'}'
330 je pcyes
331 cmp al,'~'
332 je pcyes
333 jmp pcret
334 pcwild: or bx,ParsePathWild
335 pcyes: stosb
336 cmp al,al
337 pcret: ret
338 ispchr endp
339
340
341 ; Is the current character a path separator? If so, set that flag after
342 ; storing the byte.
343
344 ispsep proc near
345 call pasep
346 jne psret
347 stosb
348 or bx,ParsePathSeparators
349 cmp al,al
350 psret: ret
351 ispsep endp
352
353
354 ; Set ZF if the character in AL is a path separator.
355
356 pasep proc near
357 cmp chSwitch,'/'
358 je bkslash
359 cmp al,'/'
360 retz
361 bkslash:cmp al,'\'
362 ret
363 pasep endp
364
365
366 ; Is the current character invalid?
367
368 isinval proc near
369 cmp al,1
370 jl inret
371 cmp al,8
372 jle inyes
373 cmp al,11
374 jl inret
375 cmp al,13
376 jne incont
377 cmp al,0
378 ret
379 incont: cmp al,31
380 jle inyes
381 cmp al,'['
382 je inyes
383 cmp al,']'
384 je inyes
385 ret
386 inyes: cmp al,al
387 inret: ret
388 isinval endp
389
390
391 ; Is the current character a dot?
392
393 isdot proc near
394 cmp al,'.'
395 jne dotret
396 stosb
397 dotret: ret
398 isdot endp
399
400
401 ; Is the current character null? If so, update SI for exiting.
402
403 ischrnull proc near
404 cmp al,0
405 jne nulret
406 dec si
407 cmp al,al
408 nulret: ret
409 ischrnull endp
410
411
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).
417
418 dirdot proc near
419 cmp byte ptr [si], '.'
420 jne diretc
421 lodsb
422 stosb
423 cmp byte ptr [si],'.'
424 jne dicont
425 lodsb
426 stosb
427 dicont: lodsb
428 call ispsep
429 je diretc
430 call issep
431 je dibk
432 call ischrnull
433 je diretd
434 direti: stc ; Invalid return
435 ret
436 dibk: dec si
437 dec di
438 diretd: cmp al,al ; Done return
439 ret
440 diretc: cmp ah,1 ; Continue return
441 clc
442 ret
443 dirdot endp
444 ENDIF
445
446 CODE ENDS
447 END