1 PAGE
90,132 ;AN000;\ f\eA\b\e2
2 TITLE DCOPYPAR
.SAL - LOOK
AT COMMAND LINE PARMS
3 ;****************** START OF SPECIFICATIONS *****************************
4 ; MODULE NAME: DCOPYPAR.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 DISKCOPY. 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 ; [d:][path] DISKCOPY [d: [d:]][/1]
23 ; [d:][path] - Path where the DISKCOPY command resides.
25 ; [d:] - To specify the Source drive
27 ; [d:] - To specify the Destination drive
29 ; [/1] - To copy only the first side of the diskette,
30 ; regardless of the diskette or drive type.
32 ; Upon entry to PARSER in this module,
33 ; "CURRENT_PARM" = offset to start of parm text in command string
34 ; "ORDINAL" = initialized to zero
35 ; PSP+81H = text of DOS command line parms string
38 ; "SOURCE_DRIVE" = CHAR OF FIRST DRIVE ID SPECIFIED, BLANK IF NONE
39 ; "TARGET_DRIVE" = CHAR OF SECOND DRIVE ID IF BOTH SPECIFIED, BLANK
40 ; IF NONE OR ONLY ONE SPECIFIED
41 ; "USER_OPTION" = 01 ON IF /1, -1 IF /1 NOT SPECIFIED.
44 ; IF ERROR, ERROR MESSAGE IS DISPLAYED, AND "EXITFL" HAS "EXPAR".
46 ; INTERNAL REFERENCES:
48 ; PARSER:NEAR Call the system Parser to decode command line
49 ; PARSE_ERROR:NEAR Display the appropriate Parse error message.
52 ; The several parameter control blocks, defined by the System
53 ; PARSER interface, defining the DISKCOPY parameters.
55 ; EXTERNAL REFERENCES:
57 ; SENDMSG:NEAR Uses Msg Descriptor to drive message handler.
58 ; SYSPARSE:NEAR System Command Line Common Parser.
61 ; EXITFL:BYTE Errorlevel return code.
62 ; MSGNUM_PARSE:WORD Message descriptor for all parse errors.
63 ; USER_OPTION:BYTE /1 parm indicator
64 ; SOURCE_DRIVE:BYTE character of first specified drive
65 ; TARGET_DRIVE:BYTE character of second specified drive
68 ; This module should be processed with the SALUT preprocessor
69 ; with the re-alignment not requested, as:
73 ; To assemble these modules, the alphabetical or sequential
74 ; ordering of segments may be used.
76 ; For LINK instructions, refer to the PROLOG of the main module,
79 ;PROGRAM AUTHOR: DOS 4.00 EMK
80 ;****************** END OF SPECIFICATIONS *****************************
82 %
OUT COMPONENT
=DISKCOPY
, MODULE
=DCOPYPAR
.SAL... ;AN000;
84 ; = = = = = = = = = = = =
85 INCLUDE PATHMAC
.INC ;AN015;PATHGEN MACRO
86 ; = = = = = = = = = = = =
87 HEADER
MACRO TEXT
;;AN000;
93 ; = = = = = = = = = = = =
94 ; $SALUT (4,23,28,36) ;AN000;
97 FALSE EQU
0 ;AN000;RETURN VALUES FOR
98 TRUE EQU
NOT FALSE
;AN000; /1 SWITCH
99 CHAR_A EQU
"A" ;AN000;ASCII VALUE OF CHARACTER "A"
100 BLANK EQU
" " ;AN001;
102 ; = = = = = = = = = = = =
103 ; EXIT CODES FROM SYSPARSE (WHEN CY=0)
105 SYSPRM_EX_OK EQU
0 ;AN000; no error
106 SYSPRM_EX_MANY EQU
1 ;AN000; too many operands
107 SYSPRM_EX_MISSING EQU
2 ;AN000; required operand missing
108 SYSPRM_EX_NOT_SWLIST EQU
3 ;AN000; not in switch list provided
109 SYSPRM_EX_NOT_KEYLIST EQU
4 ;AN000; not in keyword list provided
110 SYSPRM_EX_RANGE EQU
6 ;AN000; out of range specified
111 SYSPRM_EX_VALUE EQU
7 ;AN000; not in value list provided
112 SYSPRM_EX_STRING EQU
8 ;AN000; not in string list provided
113 SYSPRM_EX_SYNTAX EQU
9 ;AN000; syntax error
114 SYSPRM_EX_EOL EQU
-1 ;AN000; end of command line
115 ; = = = = = = = = = = = =
116 HEADER
<STRUC - DEFINITIONS OF EXTERNAL CONTROL BLOCKS
> ;AN000;
118 DB 80H
DUP (?
) ;AN000;SKIP OVER FIRST HALF OF PSP
119 PSP_PARMLEN
DB ?
;AN000;NUMBER OF BYTES IN DOS COMMAND LINE
120 PSP_COMMAND
DB 127 DUP(?
) ;AN000;TEXT OF DOS COMMAND LINE
123 MSG_DESC
STRUC ;AN003;
124 MSG_NUM
DW ?
;AN003;MESSAGE NUMBER (TO AX)
125 MSG_HANDLE
DW ?
;AN003;HANDLE OF OUTPUT DEVICE (TO BX)
126 MSG_SUBLIST
DW ?
;AN003;POINTER TO SUBLIST (TO SI)
127 MSG_COUNT
DW ?
;AN003;SUBSTITUTION COUNT (TO CX)
128 MSG_CLASS
DW ?
;AN003;MESSAGE CLASS (IN HIGH BYTE, TO DH)
129 ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL)
130 MSG_DESC ENDS
;AN003;
132 ONE_SUBS EQU
1 ;AN003;NUMBER OF VARIABLES
134 SUBLIST
STRUC ;AN000;
135 SUB_SIZE
DB ?
;AN003;SUBLIST SIZE (POINTER TO NEXT SUBLIST)
136 SUB_RES
DB ?
;AN003;RESERVED
137 ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD
138 SUB_VALUE
DW ?
;AN003;TIME, DATE, OR PTR TO DATA ITEM
139 SUB_VALUE_SEG
DW ?
;AN003;SEG ID OF PTR
140 ;(ABOVE FIELD MUST BE FILLED AT EXECUTION TIME
141 ; IF THIS IS A .COM FILE)
142 SUB_ID
DB ?
;AN003;N OF %N
143 SUB_FLAGS
DB ?
;AN003;DATA TYPE FLAGS
144 SUB_MAX_WIDTH
DB ?
;AN003;MAXIMUM FIELD WIDTH (0=UNLIMITED)
145 SUB_MIN_WIDTH
DB ?
;AN003;MINIMUM FIELD WIDTH
146 SUB_PAD_CHAR
DB ?
;AN003;CHARACTER FOR PAD FIELD
147 ; CAN BE " ", "0" OR ",".
148 ; "," CAUSES INSERTION OF THE ACTIVE
149 ; THOUSANDS SEPARATOR BETWEEN EVERY 3 DIGITS.
152 ; = = = = = = = = = = = =
153 HEADER
<PARSING WORKAREAS
> ;AN000;
154 ; $SALUT (4,14,19,36) ;AN000;
155 EXTRN EXPAR
:ABS
;AN000;ERRORLEVEL VALUE FOR BAD PARMS
156 EXTRN FINE
:ABS
;AN000;RETURN STATUS INDICATOR
157 CSEG
SEGMENT PARA
PUBLIC 'CODE' ;AN000;
158 ASSUME
CS:CSEG
,DS:CSEG
,ES:CSEG
,SS:CSEG
;AN000;
160 EXTRN SENDMSG
:NEAR ;AN000;USES MSG DESCRIPTOR TO DRIVE MESSAGE HANDLR
161 EXTRN SYSPARSE
:NEAR ;AN000;SYSTEM COMMAND LINE PARSER
163 EXTRN EXITFL
:BYTE ;AN000;ERRORLEVEL RETURN CODE
165 EXTRN SOURCE_DRIVE
:BYTE ;AN000;FIRST DRIVE LETTER SPECIFIED IN PARMS
166 EXTRN TARGET_DRIVE
:BYTE ;AN000;SECOND DRIVE LETTER SPECIFIED
168 EXTRN USER_OPTION
:BYTE ;AN000;NO OPTION (-1) /1 (1), INVALID (9)
169 NO_OPTION EQU
-1 ;AN000;NO OPTION "/1" SPECIFIED
170 OPTION_1 EQU
1 ;AN000;OPTION "/1" SPECIFIED
171 EXTRN MSGNUM_PARSE
:WORD ;AN000;MESSAGE DESCRIPTOR FOR ALL PARSE ERRORS
172 EXTRN MSGNUM_INVALID_PARM2
:WORD ;AN005;HELP INFO
173 EXTRN SUBLIST_PARSE
:WORD ;AN003;POINTS TO INVALID PARM
174 ; = = = = = = = = = = = =
176 CURRENT_PARM
DW 81H
;AN000;POINTER INTO COMMAND OF NEXT OPERAND
177 PUBLIC CURRENT_PARM
;AN000;
179 ORDINAL
DW 0 ;AN000;ORDINAL NUMBER OF WHICH PARM TO PARSE
180 PUBLIC ORDINAL
;AN000;
182 ; = = = = = = = = = = = =
183 HEADER
<DOS COMMAND LINE PARSER CONTROL BLOCKS
> ;AN000;
185 ;INPUT PARAMETERS CONTROL BLOCK, POINTED TO BY ES:DI WHEN CALLING PARSER
187 PUBLIC PARMS
;AN000;LET LINK MAKE PARMS BLOCK ADDRESSABLE
188 PARMS
LABEL BYTE ;AN000;PARMS CONTROL BLOCK
189 DW PARMSX
;AN000;POINTER TO PARMS EXTENSION
190 DB 0 ;AN000; NUMBER OF STRINGS (0, 1, 2)
191 ; NEXT LIST WOULD BE EXTRA DELIM LIST
192 ; (,& WHITESPACE ALWAYS)
193 ; NEXT LIST WOULD BE EXTRA END OF LINE LIST
196 ;SYSTEM PARSER PARAMETER EXTENSION CONTROL BLOCK
197 PARMSX
LABEL BYTE ;AN000;PARMS EXTENSION CONTROL BLOCK
198 DB 0,2 ;AN000; MIN, MAX POSITIONAL OPERANDS ALLOWED
199 DW CONTROL_POS
;AN000; DESCRIPTION OF POSITIONAL 1
200 DW CONTROL_POS
;AN000; DESCRIPTION OF POSITIONAL 2
202 DB 1 ;AN000; MAX SWITCH OPERANDS ALLOWED
203 DW CONTROL_SW
;AN000; DESCRIPTION OF SWITCH 1
205 DB 0 ;AN000; MAX KEYWORD OPERANDS ALLOWED
206 ; THERE IS NO CONTROL BLOCK
209 ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
210 HEADER
<POSITIONAL PARM DESCRIPTOR BLOCK
> ;AN000;
211 ;PARSER CONTROL BLOCK DEFINING THE ONLY POSITIONAL PARAMETER, OPTIONAL
213 ;FIRST POSITIONAL PARAMETER IS:
214 ; [D:] - SPECIFY THE SOURCE DRIVE.
216 PUBLIC CONTROL_POS
;AN000;LET LINK MAKE THIS ADDRESSABLE
217 CONTROL_POS
LABEL BYTE ;AN000;FIRST POSITIONAL DESCRIPTOR FOR FILESPEC,
219 DW 0101H ;AN000; CONTROLS TYPE MATCHED
220 ; SELECTED BITS: "DRIVE ONLY" AND "OPTIONAL"
222 ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED)
223 ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE
225 ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED)
226 ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED)
227 ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED)
228 ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED)
229 ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED)
230 ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED)
231 ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED)
232 ; 0010H=IGNORE ":" AT END IN MATCH
233 ; 0002H=REPEATS ALLOWED
236 DW 0002H ;AN000;FUNCTION_FLAGS
237 ; 0001H=CAP RESULT BY FILE TABLE
238 ; 0002H=CAP RESULT BY CHAR TABLE
239 ; 0010H=REMOVE ":" AT END
240 DW RESULT1
;AN000; RESULT BUFFER
241 DW NOVALS
;AN000; NO VALUE LISTS
242 DB 0 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS
245 ;VALUE CONTROL BLOCK FOR THE POSITIONAL PARAMETERS
246 NOVALS
DB 0 ;AN000;NO VALUE DEFINITIONS
248 ;RESULTS CONTROL BLOCK FOR THE POSITIONAL PARAMETER
249 RESULT1
LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS
250 DB 6 ;AN000; TYPE RETURNED: 0=RESERVED,
251 ; 1=NUMBER, 2=LIST INDEX,
252 ; 3=STRING, 4=COMPLEX,
253 ; 5=FILESPEC, 6=DRIVE
256 RESULT_TAG
DB 0FFH ;AN000; MATCHED ITEM TAG
257 DW 0 ;AN000;POINTER TO SYNONYM
259 RESULT_PTR1
DB ?
;AN000;DRIVE NUMBER (A=1, B=2, ETC)
261 ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
262 HEADER
<SWITCH PARM DESCRIPTOR BLOCK
> ;AN000;
263 ;PARSER CONTROL BLOCK DEFINING THE ONLY SWITCH, OPTIONAL
265 ;THE SWITCH IS "/1", MEANING ONLY COPY FIRST SIDE.
267 PUBLIC CONTROL_SW
;AN000;LET LINK MAKE THIS ADDRESSABLE
268 CONTROL_SW
LABEL BYTE ;AN000;SWITCH DESCRIPTOR FOR /1
269 DW 0001H ;AN000; CONTROLS TYPE MATCHED
270 ;SELECTED BITS: "OPTIONAL"
271 ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED)
272 ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE
274 ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED)
275 ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED)
276 ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED)
277 ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED)
278 ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED)
279 ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED)
280 ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED)
281 ; 0010H=IGNORE ":" AT END IN MATCH
282 ; 0002H=REPEATS ALLOWED
285 DW 0002H ;AN000;FUNCTION_FLAGS
286 ; 0001H=CAP RESULT BY FILE TABLE
287 ; 0002H=CAP RESULT BY CHAR TABLE
288 ; 0010H=REMOVE ":" AT END
290 DW RESULTSW1
;AN000; RESULT BUFFER
291 DW NOVALS
;AN000; VALUE LISTS
292 DB 1 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS
294 SW_1
DB "/1",0 ;AN000; IF n >0, SWITCH 1
296 ;RESULTS CONTROL BLOCK FOR THE SWITCHES
297 RESULTSW1
LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS
298 DB 3 ;AN000; TYPE RETURNED: 0=RESERVED,
299 ; 1=NUMBER, 2=LIST INDEX,
300 ; 3=STRING, 4=COMPLEX,
301 ; 5=FILESPEC, 6=DRIVE
304 DB 0FFh ;AN000; MATCHED ITEM TAG
306 DW 0 ;AN000; SYNONYM POINTER (BASED ON ES:)
307 RESULT_PTR2
DD ?
;AN000; OFFSET OF STRING VALUE
308 ; = = = = = = = = = = = =
309 PATHLABL DCOPYPAR
;AN015;
310 HEADER
<PARSER
- ASK SYSPARM TO DECODE PARAMETERS
> ;AN000;
311 ; $SALUT (4,4,9,36) ;AN000;
312 PARSER PROC
NEAR ;AN000;
313 PUBLIC PARSER
;AN000;
315 ;INPUT: "CURRENT_PARM" = OFFSET TO NEXT PARM IN COMMAND STRING
316 ; "ORDINAL" = COUNT OF NEXT PARM TO PARSE
317 ; PSP+81H = TEXT OF DOS COMMAND LINE PARMS STRING
318 ;OUTPUT: "SOURCE_DRIVE" = VALUE OF FIRST DRIVE ID SPECIFIED, 0 IF NONE
319 ; "TARGET_DRIVE" = VALUE OF SECOND DRIVE ID IF BOTH SPECIFIED, 0
320 ; IF NONE OR ONLY ONE SPECIFIED
321 ; "USER_OPTION" = "OPTION_1" IF /1 SPECIFIED, -1 IF NOT SPECIFIED
322 ; IF ERROR, ERROR MESSAGE IS DISPLAYED, AND "EXITFL" HAS "EXPAR".
323 ; DX="FINE" IF NO ERROR, OR HAS OFFSET OF PARSE ERROR DESCRIPTOR IF PROBLEM
324 ; = = = = = = = = = = = =
326 MOV USER_OPTION
, NO_OPTION
;AN000;ASSUME NO /1 IS ENTERED.
327 ; $SEARCH COMPLEX ;AN000;LOOP THRU COMMAND LINE
330 ;LOOKING AT RETURN CODE FROM SYSPARSE...
331 CMP AX,SYSPRM_EX_OK
;AN000;WERE THERE ANY ERRORS?
332 ; $EXITIF NE ;AN000;HAD A PROBLEM
334 CALL PARSE_ERROR
;AN000;DISPLAY REASON FOR ERROR
336 ; $ORELSE ;AN000;SINCE NO PROBLEM, SO FAR
339 MOV ORDINAL
,CX ;AN000;SAVE UPDATED COUNT
340 MOV CURRENT_PARM
,SI ;AN000;REMEMBER HOW FAR I GOT
341 MOV BX,DX ;AN000;SET DATA BASE REG TO POINT TO THIS OPERAND
342 CMP BX,OFFSET RESULT1
;AN000;WAS POSITIONAL PARM SPECIFIED?
343 ; $IF E ;AN000;IF POSITIONAL PARM SPECIFIED,
345 MOV SI,CX ;AN000;USE COUNT OF POSITIONALS AS INDEX
346 MOV AL,RESULT_PTR1
;AN000;GET VALUE OF DRIVE (A=1, B=2, ETC)
347 MOV SOURCE_DRIVE
-1[SI],AL ;AN000;SAVE RESPONSE VALUE
348 ;IN EITHER SOURCE_DRIVE OR TARGET_DRIVE
349 ;ACCORDING TO ORDINAL IN SI (FROM CX)
350 ; $ELSE ;AN000;SINCE NOT POSITIONAL PARM SPECIFIED
353 MOV SW_1
,BLANK
;AN001;AVOID GETTING DUPLICATE SWITCH
354 MOV USER_OPTION
,OPTION_1
;AN000;MUST HAVE BEEN THE SWITCH, /1
359 LEA DI,PARMS
;AN000; ES:DI = PARSE CONTROL DEFINITON
360 MOV SI,CURRENT_PARM
;AN000; DS:SI = COMMAND STRING, NEXT PARM
361 XOR DX,DX ;AN000; RESERVED, INIT TO ZERO
362 MOV CX,ORDINAL
;AN000; OPERAND ORDINAL, INITIALLY ZERO
363 CALL SYSPARSE
;AN000;LOOK AT DOS PARMS
365 ; BL=TERMINATED DELIMETER CODE
366 ; CX=NEW OPERAND ORDINAL
367 ; SI=SET TO PAST SCANNED OPERAND
368 ; DX=SELECTED RESULT BUFFER
369 CMP AX,SYSPRM_EX_EOL
;AN000; IS THAT THE END OF THE PARMS?
370 ;IF NOT, LOOP BACK AND FIND OUT
372 ; $ENDLOOP E ;AN000;END OF LIST
374 MOV DX,FINE
;AN000;REPORT THAT PARSER WENT OK
375 ; $ENDSRCH ;AN000;FINISHED WITH DOS COMMAND LINE
377 RET ;AN000;RETURN TO CALLER
379 ; = = = = = = = = = = = =
380 HEADER
<PARSE_ERROR
- DISPLAY REASON FOR PARSE ERROR
> ;AN000;
381 PARSE_ERROR PROC
NEAR ;AN000;
382 ;INPUT: AX - ERROR NUMBER RETURNED FROM PARSE.
383 ; "CURRENT_PARM" - OFFSET TO WHERE THE BAD PARM STARTED
384 ;OUTPUT: APPROPRIATE ERROR MESSAGE IS PREPARED FOR DISPLAY.
385 ; DX IS SET TO OFFSET OF PARSE ERROR DESCRIPTOR.
386 ; = = = = = = = = = = = =
388 MOV MSGNUM_PARSE
,AX ;AN000;PASS MESSAGE NUMBER TO DESCRIPTOR
389 MOV EXITFL
,EXPAR
;AN000;ERRORLEVEL CODE TO "PARM ERROR"
390 MOV AX,CURRENT_PARM
;AN003;GET POINTER TO START OF BAD PARM
391 CMP SI,AX ;AN003;HAS THE INDEX TO COMMAND LINE MOVED?
392 ; $IF NE ;AN003;YES, THERE IS A FAULTY PARM
394 MOV BYTE PTR [SI],NUL
;AN003;DELIMIT THE BAD PARM
395 MOV SUBLIST_PARSE
.SUB_VALUE
,AX ;AN000;POINT SUBLIST TO BAD PARM
397 MOV MSGNUM_PARSE
.MSG_SUBLIST
,OFFSET SUBLIST_PARSE
;AN003;POINT TO SUBLIST
398 MOV MSGNUM_PARSE
.MSG_COUNT
,ONE_SUBS
;AN003;SET COUNT OF SUBLISTS TO ONE
399 ; $ENDIF ;AN003;INDEX MOVED?
401 MOV DI,OFFSET MSGNUM_PARSE
;AC005;PASS BACK OFFSET TO PARSE ERR DESCRIPTOR
402 CALL SENDMSG
;AN005;DISPLAY THE ERROR MESSAGE
404 ; "Do not specify filename(s)",CR,LF
405 ; "Command Format: DISKCOPY d: d: [/1]",CR,LF
406 MOV DX,OFFSET MSGNUM_INVALID_PARM2
;AN005;DISPLAY HELP INFO
407 RET ;AN000;RETURN TO CALLER
408 PARSE_ERROR ENDP
;AN000;
409 ; = = = = = = = = = = = =
410 PATHLABL DCOPYPAR
;AN015;