summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/PARSE.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/DOS/PARSE.ASM')
-rw-r--r--v4.0/src/DOS/PARSE.ASM447
1 files changed, 447 insertions, 0 deletions
diff --git a/v4.0/src/DOS/PARSE.ASM b/v4.0/src/DOS/PARSE.ASM
new file mode 100644
index 0000000..f8de345
--- /dev/null
+++ b/v4.0/src/DOS/PARSE.ASM
@@ -0,0 +1,447 @@
1; SCCSID = @(#)parse.asm 1.2 85/07/23
2TITLE PARSE - Parsing system calls for MS-DOS
3NAME 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;
19include dosseg.asm
20
21CODE SEGMENT BYTE PUBLIC 'CODE'
22 ASSUME SS:DOSGROUP,CS:DOSGROUP
23
24.xcref
25INCLUDE DOSSYM.INC
26INCLUDE DEVSYM.INC
27.cref
28.list
29
30BOGUS =FALSE
31.lall
32 I_Need chSwitch,BYTE
33
34BREAK <$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
54ASSUME DS:NOTHING,ES:NOTHING
55
56 invoke MAKEFCB
57 PUSH SI
58 invoke get_user_stack
59 POP [SI.user_SI]
60 return
61EndProc $PARSE_FILE_DESCRIPTOR
62
63
64IF BOGUS
65BREAK <$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;------------------------------------------------------------------------------
106ParseClassMask equ 1110000000000000b ; Token class mask
107ParseSwitch equ 1000000000000000b ; Switch class
108ParseSeparators equ 0100000000000000b ; Separator class
109ParsePathName equ 0010000000000000b ; Path class
110ParsePathNameData equ 0000000000001111b ; Path token data mask
111ParsePathSynErr equ 0000000000000001b ; Path has syntax error
112ParsePathWild equ 0000000000000010b ; Path has wildcards
113ParsePathSeparators equ 0000000000000100b ; Path has pseparators
114ParseInvalidDrive 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
120Table segment
121Public PRS001S,PRS001E
122PRS001S label byte
123sepchrs db 9,10,13,' ','+',',',';','=' ; tab cr lf sp + , ; =
124seplen equ $-sepchrs
125PRS001E label byte
126table ends
127
128Procedure $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
149inval: 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
154icont: dec si
155 jmp ptosep
156
157switch: mov bx,ParseSwitch ; found a switch, set flag and parse
158 jmp ptosep ; the rest of it
159
160separ: mov bx,ParseSeparators ; found separator, set flag and parse
161seloop: lodsb ; everything up to the next non
162 call issep ; separator character
163 je seloop
164 jmp bksi
165
166path: 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
173pcont1: cmp al,'.'
174 jne pcont2
175 dec si
176 dec di
177 jmp rcont
178pcont2: 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
182drive: 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,' '
188dcont1: sub al,'@'
189 invoke GetthisDrv
190 lodsb
191 stosb
192 jc dcont2
193 jmp dcont3
194dcont2: or bx,ParseInvalidDrive
195dcont3: dec cx
196 lodsb
197 call ispsep
198 je rcont
199 dec si
200
201repeat: 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
206rcont: call dirdot
207 je done
208 jc inval
209 mov cx,8
210 mov dx,8
211 jmp name
212
213name1: dec cx
214name: lodsb ; parse and verify a file name
215 call ispchr
216 jne ncheck
217 xor ah,ah
218nloop: loop name
219 lodsb
220
221ncheck: cmp ah,0
222 jne ncont
223 cmp cx,dx
224 jne ncont
225 jmp inval
226ncont: call isdot
227 je ext
228 jmp dcheck
229
230ext: mov cx,3 ; parse and verify a file extension
231 mov dx,3
232extl: lodsb
233 call ispchr
234 jne echeck
235eloop: loop extl
236 lodsb
237
238echeck: cmp cx,dx
239 jne dcheck
240 jmp inval
241
242dcheck: 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
250ptosep: 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
258ptcont: stosb
259 jmp ptosep
260
261bkboth: dec di ; clean up when the end of the token
262bksi: dec si ; is found, stick a terminating null
263done: 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
271Endproc $PathParse
272
273; Is current character the beginning of a switch?
274
275isswit proc near
276 cmp al,[chSwitch]
277 jne swret
278 stosb
279swret: ret
280isswit endp
281
282
283; Is the current character a separator?
284
285issep 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
297sepyes: stosb
298sepret: pop cx
299 ret
300issep endp
301
302
303; Is the current character a path character? If it is a wildcard char too,
304; set that flag.
305
306ispchr 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
334pcwild: or bx,ParsePathWild
335pcyes: stosb
336 cmp al,al
337pcret: ret
338ispchr endp
339
340
341; Is the current character a path separator? If so, set that flag after
342; storing the byte.
343
344ispsep proc near
345 call pasep
346 jne psret
347 stosb
348 or bx,ParsePathSeparators
349 cmp al,al
350psret: ret
351ispsep endp
352
353
354; Set ZF if the character in AL is a path separator.
355
356pasep proc near
357 cmp chSwitch,'/'
358 je bkslash
359 cmp al,'/'
360 retz
361bkslash:cmp al,'\'
362 ret
363pasep endp
364
365
366; Is the current character invalid?
367
368isinval 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
379incont: cmp al,31
380 jle inyes
381 cmp al,'['
382 je inyes
383 cmp al,']'
384 je inyes
385 ret
386inyes: cmp al,al
387inret: ret
388isinval endp
389
390
391; Is the current character a dot?
392
393isdot proc near
394 cmp al,'.'
395 jne dotret
396 stosb
397dotret: ret
398isdot endp
399
400
401; Is the current character null? If so, update SI for exiting.
402
403ischrnull proc near
404 cmp al,0
405 jne nulret
406 dec si
407 cmp al,al
408nulret: ret
409ischrnull 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
418dirdot 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
427dicont: lodsb
428 call ispsep
429 je diretc
430 call issep
431 je dibk
432 call ischrnull
433 je diretd
434direti: stc ; Invalid return
435 ret
436dibk: dec si
437 dec di
438diretd: cmp al,al ; Done return
439 ret
440diretc: cmp ah,1 ; Continue return
441 clc
442 ret
443dirdot endp
444ENDIF
445
446CODE ENDS
447 END