2 TITLE XCOPYPAR
.SAL - LOOK
AT COMMAND LINE PARMS
3 ;****************** START OF SPECIFICATIONS *****************************
4 ; MODULE NAME: XCOPYPAR.SAL
6 ; DESCRIPTIVE NAME: Handle the definition of the DOS command line parameters
7 ; and the interface to the DOS system PARSER.
9 ;FUNCTION: The static data areas are prescribed by the DOS system PARSER
10 ; to define the several parameters presented to XCOPY. These
11 ; data areas are passed to the PARSER, and its responses checked
12 ; to determine the nature of the user's specifications. Any errors
13 ; found in the user's parameters are defined in messages back
16 ; ENTRY POINT: PARSER, near
18 ; INPUT: (DOS COMMAND LINE PARAMETERS)
20 ; SOURCE OPERAND: TARGET OPERAND:
22 ; [d:] [path] filename[.ext] [d:] [path] [filename[.ext]]
24 ; [d:] path [filename[.ext]]
26 ; d: [path] [filename[.ext]]
30 ; [d:] - To specify the Source drive
32 ; [d:] - To specify the Destination drive
37 ; /A /D /E /M /P /S /V /W
40 ; Upon entry to PARSER in this module,
41 ; "CURRENT_PARM" = offset to start of parm text in command string
42 ; "ORDINAL" = initialized to zero
43 ; PSP+81H = text of DOS command line parms string
49 ; INTERNAL REFERENCES:
51 ; PARSE_ERROR:NEAR Display the appropriate Parse error message.
54 ; The several parameter control blocks, defined by the System
55 ; PARSER interface, defining the XCOPY parameters.
57 ; EXTERNAL REFERENCES:
59 ; SYSPARSE:NEAR System Command Line Common Parser.
62 ; EXITFL:BYTE Errorlevel return code.
63 ; MSGNUM_PARSE:WORD Message descriptor for all parse errors.
66 ; This module should be processed with the SALUT preprocessor
67 ; with the re-alignment not requested, as:
71 ; To assemble these modules, the alphabetical or sequential
72 ; ordering of segments may be used.
74 ; For LINK instructions, refer to the PROLOG of the main module,
77 ; REVISION HISTORY: A000 Version 4.00: add PARSER, System Message Handler,
78 ; Ignore unique volume serial number differences
79 ; A004 PTM0700 9/02/87 Avoid duplicate switches and
80 ; display parm in error.
82 ; Label: "The DOS XCOPY Utility"
83 ; "Version 4.00 (C)Copyright 1988 Microsoft"
84 ; "Licensed Material - Program Property of Microsoft "
86 ;****************** END OF SPECIFICATIONS *****************************
88 %
OUT COMPONENT
=XCOPY
, MODULE
=XCOPYPAR
.SAL...
90 ; = = = = = = = = = = = =
97 ; = = = = = = = = = = = =
101 INIT_ERROR_FLAG EQU 80H
;AN000;critical initialization error. Should abort
102 CMD_BUF_SIZE EQU
127 ;AN000;NUMBER BYTES IN DOS COMMAND LINE BUFFER
103 ZERO EQU
0 ;AN000;COMPARAND FOR CLEARED REG
104 NUL EQU
0 ;AN000;DELIMITER FOR ASCIIZ STRINGS
106 ; = = = = = = = = = = = =
108 ; PARSER ASSEMBLE SWITCHES
110 FarSW EQU
0 ;AN000;CALL THE PARSER BY FAR CALL
111 DateSW EQU
1 ;AN000;DATE FORMAT
112 TimeSW EQU
1 ;AN000;TIME FORMAT
113 FileSW EQU
1 ;AN000;FILE SPECIFICATION
114 CAPSW EQU
1 ;AN000;USE FILE TABLE CAPS
115 CmpxSW EQU
0 ;AN000;COMPLEX LIST
116 DrvSW EQU
1 ;AN000;DRIVE ONLY FORMAT
117 QusSW EQU
0 ;AN000;QUOTED STRING
118 NumSW EQU
1 ;AN000;NUMERIC VALUE
119 KeySW EQU
0 ;AN000;KEYWORDS
120 SwSW EQU
1 ;AN000;SWITCHES
121 Val1SW EQU
0 ;AN000;VALUE DEFINITION #1
122 Val2SW EQU
0 ;AN000;VALUE DEFINITION #2
123 Val3SW EQU
0 ;AN000;VALUE DEFINITION #3
124 ; = = = = = = = = = = = =
125 ; EXIT CODES FROM SYSPARSE (WHEN CY=0)
127 SYSPRM_EX_OK EQU
0 ;AN000; no error
128 SYSPRM_EX_MANY EQU
1 ;AN000; too many operands
129 SYSPRM_EX_MISSING EQU
2 ;AN000; required operand missing
130 SYSPRM_EX_NOT_SWLIST EQU
3 ;AN000; not in switch list provided
131 SYSPRM_EX_NOT_KEYLIST EQU
4 ;AN000; not in keyword list provided
132 SYSPRM_EX_RANGE EQU
6 ;AN000; out of range specified
133 SYSPRM_EX_VALUE EQU
7 ;AN000; not in value list provided
134 SYSPRM_EX_STRING EQU
8 ;AN000; not in string list provided
135 SYSPRM_EX_SYNTAX EQU
9 ;AN000; syntax error
136 SYSPRM_EX_EOL EQU
-1 ;AN000; end of command line
137 ; = = = = = = = = = = = =
139 HEADER
<STRUC - DEFINITIONS OF EXTERNAL CONTROL BLOCKS
>
140 ; $SALUT (4,17,22,36)
142 DB 80H
DUP (?
) ;AN000;SKIP OVER FIRST HALF OF PSP
143 PSP_PARMLEN
DB ?
;AN000;NUMBER OF BYTES IN DOS COMMAND LINE
144 PSP_COMMAND
DB 127 DUP(?
) ;AN000;TEXT OF DOS COMMAND LINE
146 ; = = = = = = = = = = = =
147 CSEG
SEGMENT PUBLIC ;AN000;PLACE HOLDER FOR PARSE CODE
149 DGROUP GROUP DSEG
, DSEG_INIT
150 DSEG
SEGMENT PARA
PUBLIC
153 DSEG_INIT
SEGMENT PARA
PUBLIC
155 INCLUDE PSDATA
.INC ;AN018;WORK AREA USED BY PARSE.ASM
157 ;--- EXTERNAL VARIABLES ---
158 EXTRN PARM_FLAG
: BYTE ;AN000;
160 %
OUT COMPONENT
=XCOPY
, SUBCOMPONENT
=PARSE
163 COMMAND_LINE
DB 127 DUP(?
) ;AN000;TEXT OF DOS COMMAND LINE (INTERNAL USE)
166 CURRENT_PARM
DW DGROUP
:COMMAND_LINE
;AN000;POINTER INTO COMMAND OF NEXT
170 ORDINAL
DW 0 ;AN000;ORDINAL NUMBER OF WHICH PARM TO PARSE
173 TAR_DRIVE
DB " " ;AN000;TARGET DRIVE LETTER SPECIFIED IN PARMS
174 SO_DRIVE
DB " " ;AN000;SOURCE DRIVE LETTER SPECIFIED
175 PUBLIC TAR_DRIVE
,SO_DRIVE
;AN000;PASS RESULTS TO INIT ROUTINE
177 ; = = = = = = = = = = = =
178 HEADER
<DOS COMMAND LINE PARSER CONTROL BLOCKS
>
180 ;INPUT PARAMETERS CONTROL BLOCK, POINTED TO BY ES:DI WHEN CALLING PARSER
182 PUBLIC PARMS
;AN000;LET LINK MAKE PARMS BLOCK ADDRESSABLE
183 PARMS
LABEL BYTE ;AN000;PARMS CONTROL BLOCK
184 DW DGROUP
:PARMSX
;AN000;POINTER TO PARMS EXTENSION
185 DB 0 ;AN000; NUMBER OF STRINGS (0, 1, 2)
186 DB 1 ;AN000; NUMBER OF ADDITIONAL DELIMITERS
187 DB ";" ;AN000; ADDITIONAL DELIMITER
190 ;SYSTEM PARSER PARAMETER EXTENSION CONTROL BLOCK
191 PARMSX
LABEL BYTE ;AN000; PARMS EXTENSION CONTROL BLOCK
192 DB 1,2 ;AN000; MIN, MAX POSITIONAL OPERANDS ALLOWED
193 DW DGROUP
:CONTROL_POS1
;AN000; DESCRIPTION OF POSITIONAL 1
194 DW DGROUP
:CONTROL_POS2
;AN000; DESCRIPTION OF POSITIONAL 2
196 DB 2 ;AN000; THERE ARE 8 SWITCHES IN 2 GROUPS
197 ;AN000; (/A, /E, /M, /P, /S, /V, /W, /D)
198 DW DGROUP
:SW1_7
;AN000; POINTER TO THE SWITCH DEFINITION AREA
199 DW DGROUP
:SW8
;AN000; POINTER TO EIGHTH SWITCH DEFINITION AREA
201 DB 0 ;AN000; MAX KEYWORD OPERANDS ALLOWED
202 ;AN000; THERE IS NO CONTROL BLOCK
203 ;AN000; DEFINING KEYWORDS
205 ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
206 HEADER
<POSITIONAL PARM DESCRIPTOR BLOCK
>
207 ;PARSER CONTROL BLOCK DEFINING THE ONLY POSITIONAL PARAMETER, OPTIONAL
209 ;FIRST POSITIONAL PARAMETER IS:
211 ; [d:] [path] filename[.ext]
213 ; [d:] path [filename[.ext]]
215 ; d: [path] [filename[.ext]]
217 PUBLIC CONTROL_POS1
;AN000; LET LINK MAKE THIS ADDRESSABLE
218 CONTROL_POS1
LABEL BYTE ;AN000; FIRST POSITIONAL DESCRIPTOR FOR FILESPEC
220 DW 0200H ;AN000; CONTROLS TYPE MATCHED
221 ; SELECTED BITS: "FILE SPEC"
223 ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED)
224 ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE
226 ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED)
227 ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED)
228 ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED)
229 ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED)
230 ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED)
231 ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED)
232 ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED)
233 ; 0010H=IGNORE ":" AT END IN MATCH
234 ; 0002H=REPEATS ALLOWED
237 DW 0002H ;AN000; FUNCTION_FLAGS
238 ; 0001H=CAP RESULT BY FILE TABLE
239 ; 0002H=CAP RESULT BY CHAR TABLE
240 ; 0010H=REMOVE ":" AT END
241 DW DGROUP
:RESULT1
;AN000; RESULT BUFFER (FIRST)
243 DW DGROUP
:NOVALS
;AN000; NO VALUE LISTS
244 DB 0 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS
245 ;AN000; IN FOLLOWING LIST
247 ;SECOND POSITIONAL PARAMETER IS:
249 ; [d:] [path] [filename[.ext]]
251 PUBLIC CONTROL_POS2
;AN000; LET LINK MAKE THIS ADDRESSABLE
252 CONTROL_POS2
LABEL BYTE ;AN000; SECOND POSITIONAL DESCRIPTOR FOR FILESPEC,
254 DW 0201H ;AN000; CONTROLS TYPE MATCHED
255 ;AN000; SELECTED BITS: "FILE SPEC"
256 DW 0002H ;AN000; FUNCTION_FLAGS
257 DW DGROUP
:RESULT2
;AN000; RESULT BUFFER (SECOND)
258 DW DGROUP
:NOVALS
;AN000; NO VALUE LISTS
259 DB 0 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS
260 ;AN000; IN FOLLOWING LIST
263 ;VALUE CONTROL BLOCK FOR THE POSITIONAL PARAMETERS
264 NOVALS
DB 0 ;AN000;NO VALUE DEFINITIONS
266 ;RESULTS CONTROL BLOCK FOR THE FIRST POSITIONAL PARAMETER
267 RESULT1
LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS
268 TYPE1
DB 0 ;AN000; TYPE RETURNED: 0=RESERVED,
270 ;AN000; 1=NUMBER, 2=LIST INDEX,
271 ;AN000; 3=STRING, 4=COMPLEX,
272 ;AN000; 5=FILESPEC, 6=DRIVE
273 ;AN000; 7=DATE, 8=TIME
274 ;AN000; 9=QUOTED STRING
275 RESULT_TAG1
DB 0FFH ;AN000; MATCHED ITEM TAG
276 DW 0 ;AN000; POINTER TO SYNONYM
278 RESULT_PTR1
DD 0 ;AN000; FILESPEC OFFSET
281 ;RESULTS CONTROL BLOCK FOR THE SECOND POSITIONAL PARAMETER
282 RESULT2
LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS
284 TYPE2
DB 0 ;AN000; TYPE RETURNED: 0=RESERVED,
286 ;AN000; 1=NUMBER, 2=LIST INDEX,
287 ;AN000; 3=STRING, 4=COMPLEX,
288 ;AN000; 5=FILESPEC, 6=DRIVE
289 ;AN000; 7=DATE, 8=TIME
290 ;AN000; 9=QUOTED STRING
291 RESULT_TAG2
DB 0FFH ;AN000; MATCHED ITEM TAG
292 DW 0 ;AN000; POINTER TO SYNONYM
294 RESULT_PTR2
DD 0 ;AN000; FILESPEC OFFSET
297 ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
298 HEADER
<SWITCH PARM DESCRIPTOR BLOCK
>
299 ;PARSER CONTROL BLOCK DEFINING THE SWITCHES, OPTIONAL
301 PUBLIC SW1_7
;AN000;LET LINK MAKE THIS ADDRESSABLE
302 SW1_7
LABEL BYTE ;AN000;SWITCH DESCRIPTOR FOR THE FIRST SEVEN SW
303 DW 0001H ;AN000; CONTROLS TYPE MATCHED
304 ;SELECTED BITS: "OPTIONAL"
305 ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED)
306 ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE
308 ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED)
309 ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED)
310 ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED)
311 ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED)
312 ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED)
313 ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED)
314 ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED)
315 ; 0010H=IGNORE ":" AT END IN MATCH
316 ; 0002H=REPEATS ALLOWED
319 DW 0002H ;AN000; FUNCTION_FLAGS
320 ; 0001H=CAP RESULT BY FILE TABLE
321 ; 0002H=CAP RESULT BY CHAR TABLE
322 ; 0010H=REMOVE ":" AT END
324 DW DGROUP
:RESULTSW1
;AN000; RESULT BUFFER
325 PUBLIC RESULTSW1
;AN000;LET LINK MAKE THIS ADDRESSABLE
326 DW DGROUP
:NOVALS
;AN000; VALUE LISTS
327 DB 7 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS
328 ;AN000; IN FOLLOWING LIST
344 ;PARSER CONTROL BLOCK DEFINING THE DATE SWITCH, OPTIONAL
346 PUBLIC SW8
;AN000; LET LINK MAKE THIS ADDRESSABLE
347 SW8
LABEL BYTE ;AN000; SWITCH DESCRIPTOR FOR THE DATE SW
348 DW 1000H
;AN000; CONTROLS TYPE MATCHED
349 DW 0000H ;AN000; FUNCTION_FLAGS
350 DW DGROUP
:DATE_BUFF
;AN000; RESULT BUFFER
351 DW DGROUP
:NOVALS
;AN000; VALUE LISTS
352 DB 1 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS
353 ;AN000; IN FOLLOWING LIST
359 ;RESULTS CONTROL BLOCK FOR THE /A,/E,/M,/P,/S,/V,/W SWITCHES
360 RESULTSW1
LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS
361 DB 3 ;AN000; TYPE RETURNED: 0=RESERVED,
362 ; 1=NUMBER, 2=LIST INDEX,
363 ; 3=STRING, 4=COMPLEX,
364 ; 5=FILESPEC, 6=DRIVE
367 DB 0FFh ;AN000; MATCHED ITEM TAG
369 RESULTSWSYN
DW 0 ;AN000; SYNONYM POINTER (BASED ON ES:)
371 RESULTSWVAL
DD 0 ;AN000; OFFSET OF STRING VALUE
375 ;RESULT CONTROL BLOCK FOR THE /D SWITCH
377 DB 7 ;AN000; TYPE RETURNED (DATE)
378 DB 0FFh ;AN000; MATCHED ITEM TAG
379 DW 0 ;AN000; SYNONYM POINTER (BASED ON ES:)
380 DATE_YEAR
DW 0 ;AN000; YEAR
382 DATE_MONTH
DB 0 ;AN000; MONTH
384 DATE_DAY
DB 0 ;AN000; DAY
388 ; = = = = = = = = = = = =
390 HEADER
<PARSING WORKAREAS
>
391 ; $SALUT (4,14,19,36)
393 ASSUME
CS:CSEG
, DS:DGROUP
, ES:DGROUP
395 PUBLIC SYSPARSE
;AN000;SUBROUTINE ENTRY POINT ;AN000;
399 %
OUT COMPONENT
=XCOPY
, SUBCOMPONENT
=PARSE
, MODULE
=PARSE
.ASM
...
401 INCSW EQU
0 ;AN018;TELL PARSE.ASM PSDATA.INC IS INCLUDED
402 BASESW EQU
1 ;AN018;PSDATA.INC IS ADDRESSABLE WITH DS
403 ; INCLUDE PARSE.ASM ;AN000;GENERATED CODE SUPPRESSED FROM LISTING
410 EXTRN GET_PARMS
:NEAR ;AN000;COMMAND LINE PARMS AND OPTIONS PROCESSING
412 HEADER
<PARSER
- ASK SYSPARM TO DECODE PARAMETERS
>
417 ;INPUT: CURRENT_PARM = OFFSET TO NEXT PARM IN COMMAND STRING
418 ; COMMAND_LINE = COPY OF DOS COMMAND LINE PARAMETERS
419 ; "ORDINAL" = COUNT OF NEXT PARM TO PARSE
420 ;OUTPUT: CARRY IS SET IF THERE WAS A PROBLEM, AX HAS PARSE RET CODE.
421 ; CARRY IS CLEAR IF ALL OK WITH THE PARMS
422 ;THE PSP IS NOT REFERENCED, SINCE THE PARMS HAVE BEEN MOVED OUT OF THERE.
425 MOV ORDINAL
,ZERO
;AN000;OPERAND ORDINAL, INITALLY ZERO
426 ; $SEARCH COMPLEX ;AN000;LOOP THRU COMMAND LINE
429 ;AN000;LOOKING AT RETURN CODE IN AX,
430 ;AN000; JUST PRODUCED BY SYSPARSE...
431 CMP AX,ZERO
;AN000;WERE THERE ANY ERRORS?
432 ; $EXITIF NE,OR ;AN000;HAD A PROBLEM
434 MOV ORDINAL
,CX ;AN000;SAVE UPDATED COUNT
435 MOV CURRENT_PARM
,SI ;AN000;REMEMBER HOW FAR I GOT
436 MOV BX,DX ;AN000;SET DATA BASE REG TO POINT TO THIS OPERAND
437 CALL GET_PARMS
;AN000;GET 1ST AND 2ND PARAMETERS
438 TEST PARM_FLAG
,INIT_ERROR_FLAG
;AN000;CRITICAL PARAMETER ERROR HAS OCCURRED
439 ; $EXITIF NZ ;AN000;HAD A PROBLEM
442 STC ;AN000;SET CARRY TO INDICATE ERROR
443 CALL PARM_ERROR
;AN000;GET OUT WITH ERROR INFORMATION
444 ;AN000;EITHER PARAMETER OR PARSER ERROR PROCESSED
447 ; $ORELSE ;AN000;SINCE NO PROBLEM, SO FAR
453 LEA DI,PARMS
;AN000; ES:DI = PARSE CONTROL DEFINITON
454 MOV SI,CURRENT_PARM
;AN000; DS:SI = COMMAND STRING, NEXT PARM
455 XOR DX,DX ;AN000; RESERVED, INIT TO ZERO
456 MOV CX,ORDINAL
;AN000; OPERAND ORDINAL, INITIALLY ZERO
459 ;AN000; BL=TERMINATED DELIMITER CODE
460 ;AN000; CX=NEW OPERAND ORDINAL
461 ;AN000; SI=SET TO PAST SCANNED OPERAND
462 ;AN000; DX=SELECTED RESULT BUFFER
463 CMP AX,SYSPRM_EX_EOL
;AN000; IS THAT THE END OF THE PARMS?
464 ;AN000;IF NOT, LOOP BACK AND FIND OUT
465 ;AN000; WHAT THAT PARM IS
466 ; $ENDLOOP E ;AN000;END OF LIST
468 CLC ;AN000;CLEAR CARRY, END OF LIST OK
471 RET ;AN000;RETURN TO CALLER
473 ; = = = = = = = = = = = =
474 HEADER
<PARM_ERROR
- ????????????
>
476 ;INPUT: DX - ADDRESS OF MESSAGE TEXT
477 ; PARM_FLAG set to INIT_ERROR_FLAG (critical error)
478 ; OR THERE WAS A PARSER ERROR
480 RET ;AN000;RETURN TO CALLER WITH C SET
485 ; = = = = = = = = = = = =