PAGE 90,132 ;AN000;A2 TITLE GRTABPAR.SAL - LOOK AT COMMAND LINE PARMS ;AN000; ;****************** START OF SPECIFICATIONS ***************************** ; MODULE NAME: GRTABPAR.SAL ; DESCRIPTIVE NAME: Handle the definition of the DOS command line parameters ; and the interface to the DOS system PARSER. ;FUNCTION: The static data areas are prescribed by the DOS system PARSER ; to define the several parameters presented to GRAFTABL. These ; data areas are passed to the PARSER, and its responses checked ; to determine the nature of the user's specifications. Any errors ; found in the user's parameters are defined in messages back ; to the user. ; ENTRY POINT: PARSER, near ; INPUT: (DOS COMMAND LINE PARAMETERS) ; [d:][path] GRAFTABL [cp|?|/STA|/STATUS] ; WHERE ; [d:][path] - Path where the GRAFTABL command resides. ; [cp] - Codepage number to be loaded. If blank, ; 437 is assumed ; [?] - This requests a display of the parameters ; supported by the GRAFTABL command. ; [/STATUS] - (May be shortened to just /STA.) This ; requests the current codepage already ; loaded by a previous GRAFTABL, if any, ; be displayed. ; Upon entry to PARSER in this module, ; "CURRENT_PARM" = offset to start of parm text in command string ; "ORDINAL" = initialized to zero ; PSP+81H = text of DOS command line parms string ; EXIT-NORMAL: If a Code Page number was specified ; BX = Offset to language table to be loaded ; DX = Integer value of Code Page specified ; If /STATUS (or /STA) was specified ; BX = 0 ; If Question mark was specified ; BX=-1 ; EXIT-ERROR: If there was any problem with the parms, ; the question mark is assumed, and the appropriate ; PARSE error message is displayed. ; The Errorlevel code of "EXPAR" (3), meaning: "PARM ERROR", ; set in "EXITFL", is requested to be returned to the user. ; INTERNAL REFERENCES: ; ROUTINES: ; PARSE_ERROR:NEAR Display the appropriate Parse error message. ; DATA AREAS: ; The several parameter control blocks, defined by the System ; PARSER interface, defining the GRAFTABL parameters. ; EXTERNAL REFERENCES: ; ROUTINES: ; SENDMSG:NEAR Uses Msg Descriptor to drive message handler. ; SYSPARSE:NEAR System Command Line Common Parser. ; DATA AREAS: ; TABLEUS:BYTE First table of Fonts, happens to be the USA version. ; (Format of language Font defined in LANGUAGE STRUC.) ; EXITFL:BYTE Errorlevel return code. ; MSGNUM_PARSE:WORD Message descriptor for all parse errors. ; ACTIVECPID:WORD Pointer to CPID entry of active entry, where the ; CPID table is a set of 4 byte asciiz strings, ; each defining the number of a Code Page font. ; NOTES: ; This module should be processed with the SALUT preprocessor ; with the re-alignment not requested, as: ; SALUT GRTABPAR,NUL ; To assemble these modules, the alphabetical or sequential ; ordering of segments may be used. ; For LINK instructions, refer to the PROLOG of the main module, ; GRTAB.SAL. ; REVISION HISTORY: ; A001 PTM 382 display "ACTIVE" OR "PREVIOUS" CP. ; A002 PTM 474 Avoid duplicate switches ; A003 PTM 538 Display parm in error ;****************** END OF SPECIFICATIONS ***************************** IF1 ;AN000; %OUT COMPONENT=GRAFTABL, MODULE=GRTABPAR.SAL... ;AN000; ENDIF ;AN000; ; = = = = = = = = = = = = INCLUDE PATHMAC.INC ;AN006; ; = = = = = = = = = = = = HEADER MACRO TEXT ;;AN000; .XLIST ;AN000; SUBTTL TEXT ;AN000; .LIST ;AN000; PAGE ;AN000; ENDM ;;AN000; ; = = = = = = = = = = = = ; $SALUT (4,23,28,36) ;AN000; EXTRN CPID_L:ABS ;AN000;BYTES PER CPID ENTRY MSG_DESC STRUC ;AN003; MSG_NUM DW ? ;AN003;MESSAGE NUMBER (TO AX) MSG_HANDLE DW ? ;AN003;HANDLE OF OUTPUT DEVICE (TO BX) MSG_SUBLIST DW ? ;AN003;POINTER TO SUBLIST (TO SI) MSG_COUNT DW ? ;AN003;SUBSTITUTION COUNT (TO CX) MSG_CLASS DW ? ;AN003;MESSAGE CLASS (IN HIGH BYTE, TO DH) ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL);AN003; MSG_DESC ENDS ;AN003; ONE_SUBS EQU 1 ;AN003;NUMBER OF VARIABLES SUBLIST STRUC ;AN000; SUB_SIZE DB ? ;AN003;SUBLIST SIZE (POINTER TO NEXT SUBLIST) SUB_RES DB ? ;AN003;RESERVED ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD ;AN003; SUB_VALUE DW ? ;AN003;TIME, DATE, OR PTR TO DATA ITEM SUB_VALUE_SEG DW ? ;AN003;SEG ID OF PTR ;(ABOVE FIELD MUST BE FILLED AT EXECUTION TIME ;AN003; ; IF THIS IS A .COM FILE) ;AN003; SUB_ID DB ? ;AN003;N OF %N SUB_FLAGS DB ? ;AN003;DATA TYPE FLAGS SUB_MAX_WIDTH DB ? ;AN003;MAXIMUM FIELD WIDTH (0=UNLIMITED) SUB_MIN_WIDTH DB ? ;AN003;MINIMUM FIELD WIDTH SUB_PAD_CHAR DB ? ;AN003;CHARACTER FOR PAD FIELD ; CAN BE " ", "0" OR ",". ;AN003; ; "," CAUSES INSERTION OF THE ACTIVE ;AN003; ; THOUSANDS SEPARATOR BETWEEN EVERY 3 DIGITS. ;AN003; SUBLIST ENDS ;AN003; ; LOCAL EQUATES ZERO EQU 0 ;AN000;COMPARAND FOR MISSING PARMS RETCODE_QUESTION EQU -1 ;AN000;VALUE IN BX, IF PARM=? EXPAR EQU 3 ;AN000;RETURN TO DOS, INVALID DOS COMND LINE PARMS CR EQU 13 ;AN000;CARRIAGE RETURN BLANK EQU " " ;AN002;AVOIDS DUPLICATES SWITCHES NUL EQU 0 ;AN003;ASCIIZ DELIMITER ; = = = = = = = = = = = = ; EXIT CODES FROM SYSPARSE (WHEN CY=0) SYSPRM_EX_OK EQU 0 ;AN000; no error SYSPRM_EX_MANY EQU 1 ;AN000; too many operands SYSPRM_EX_MISSING EQU 2 ;AN000; required operand missing SYSPRM_EX_NOT_SWLIST EQU 3 ;AN000; not in switch list provided SYSPRM_EX_NOT_KEYLIST EQU 4 ;AN000; not in keyword list provided SYSPRM_EX_RANGE EQU 6 ;AN000; out of range specified SYSPRM_EX_VALUE EQU 7 ;AN000; not in value list provided SYSPRM_EX_STRING EQU 8 ;AN000; not in string list provided SYSPRM_EX_SYNTAX EQU 9 ;AN000; syntax error SYSPRM_EX_EOL EQU -1 ;AN000; end of command line ; = = = = = = = = = = = = HEADER ;AN000; LANGUAGE STRUC ;AN000;DEFINITION OF EACH LANGUAGE TABLE LANCHAR DB 1024 DUP(?) ;AN000;8 BYTES PER EACH OF 128 CHARACTERS LANID DW ? ;AN000;TWO BYTE CODEPAGE ID, TO MATCH ; GRAFTABL CMD LINE PARM LANNAME DB 14 DUP(?) ;AN000;ASCIIZ STRING NAME OF LANGUAGE LANGUAGE ENDS ;AN000; ; = = = = = = = = = = = = PSP STRUC ;AN000; DB 80H DUP (?) ;AN000;SKIP OVER FIRST HALF OF PSP PSP_PARMLEN DB ? ;AN000;NUMBER OF BYTES IN DOS COMMAND LINE PSP_COMMAND DB 127 DUP(?) ;AN000;TEXT OF DOS COMMAND LINE PSP ENDS ;AN000; ; = = = = = = = = = = = = HEADER ;AN000; ; $SALUT (4,14,19,36) ;AN000; CSEG SEGMENT PARA PUBLIC ;AN000; ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000; EXTRN SENDMSG:NEAR ;AN000;USES MSG DESCRIPTOR TO DRIVE MESSAGE HANDLR EXTRN SYSPARSE:NEAR ;AN000;SYSTEM COMMAND LINE PARSER EXTRN TABLEUS:BYTE ;AN000;FIRST TABLE OF FONTS EXTRN EXITFL:BYTE ;AN000;ERRORLEVEL RETURN CODE EXTRN MSGNUM_PARSE:WORD ;AN000;MESSAGE DESCRIPTOR FOR ALL PARSE ERRORS EXTRN SUBLIST_PARSE:WORD ;AN003;POINTS TO INVALID PARM EXTRN ACTIVECPID:WORD ;AN000;POINTER TO CPID ENTRY OF ACTIVE ENTRY ; = = = = = = = = = = = = CURRENT_PARM DW 81H ;AN000;POINTER INTO COMMAND OF NEXT OPERAND PUBLIC CURRENT_PARM ;AN000; ORDINAL DW 0 ;AN000;ORDINAL NUMBER OF WHICH PARM TO PARSE PUBLIC ORDINAL ;AN000; FIRST_TIME DB 0 ;AN000;INDICATES IF A PARM ALREADY FOUND PARSE_RESULT DW 0 ;AN000;TEMP, HOLDS BX TO BE RETURNED ; If a Code Page number was specified ; BX = Offset to language table to be loaded ; DX = Integer value of Code Page specified ; If /STATUS (or /STA) was specified ; BX = 0 ; If Question mark was specified ; BX=-1 ; = = = = = = = = = = = = HEADER ;AN000; ;INPUT PARAMETERS CONTROL BLOCK, POINTED TO BY ES:DI WHEN CALLING PARSER PUBLIC PARMS ;AN000;LET LINK MAKE PARMS BLOCK ADDRESSABLE PARMS LABEL BYTE ;AN000;PARMS CONTROL BLOCK DW PARMSX ;AN000;POINTER TO PARMS EXTENSION DB 0 ;AN000; NUMBER OF STRINGS (0, 1, 2) ; NEXT LIST WOULD BE EXTRA DELIM LIST ; (,& WHITESPACE ALWAYS) ; NEXT LIST WOULD BE EXTRA END OF LINE LIST ; (CR,LF,0 ALWAYS) ;SYSTEM PARSER PARAMETER EXTENSION CONTROL BLOCK PARMSX LABEL BYTE ;AN000;PARMS EXTENSION CONTROL BLOCK DB 0,1 ;AN000; MIN, MAX POSITIONAL OPERANDS ALLOWED DW CONTROL_POS ;AN000; DESCRIPTION OF POSITIONAL 1 DB 1 ;AN000; MAX SWITCH OPERANDS ALLOWED DW CONTROL_SW ;AN000; DESCRIPTION OF SWITCH 1 DB 0 ;AN000; MAX KEYWORD OPERANDS ALLOWED ; THERE IS NO CONTROL BLOCK ; DEFINING KEYWORDS ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = HEADER ;AN000; ;PARSER CONTROL BLOCK DEFINING THE ONLY POSITIONAL PARAMETER, OPTIONAL ;FIRST POSITIONAL PARAMETER IS: ; [cp|?] THE CODEPAGE NUMBER, OR THE QUESTION MARK PUBLIC CONTROL_POS ;AN000;LET LINK MAKE THIS ADDRESSABLE CONTROL_POS LABEL BYTE ;AN000;FIRST POSITIONAL DESCRIPTOR FOR FILESPEC, ; OPTIONAL DW 2001H ;AN000; CONTROLS TYPE MATCHED ; SELECTED BITS: "SIMPLE STRING" AND "OPTIONAL" ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED) ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE ; CHECKED) ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED) ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED) ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED) ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED) ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED) ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED) ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED) ; 0010H=IGNORE ":" AT END IN MATCH ; 0002H=REPEATS ALLOWED ; 0001H=OPTIONAL DW 0000H ;AN000;FUNCTION_FLAGS ("NO CAPS") ; 0001H=CAP RESULT BY FILE TABLE ; 0002H=CAP RESULT BY CHAR TABLE ; 0010H=REMOVE ":" AT END DW RESULT ;AN000; RESULT BUFFER DW VALS ;AN000; VALUE LISTS DB 0 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS ; IN FOLLOWING LIST ;VALUE CONTROL BLOCK FOR THE POSITIONAL PARAMETERS VALS DB 3 ;AN000;NUMBER OF VALS DEFINITIONS (0-3) DB 0 ;AN000;NUMBER OF RANGES (NONE) DB 0 ;AN000;NUMBER OF NUMERIC CHOICES (NONE) DB 6 ;AN000;NUMBER OF CHOICE STRINGS ;THE ORDER OF THESE VALUE DEFINITIONS IS SIGNIFICANT. THEIR ORDER MUST ;MATCH THE ORDER IN WHICH THE CORRESPONDING FONT TABLE MODULES ARE ;LINKED TOGETHER. THUE THE "VALUE RETURNED" OF 1 MEANS THE FIRST LINKED ;FONT TABLE, THE VALUE OF 5 MEANS THE FIFTH LINKED FONT TABLE, ETC. VAL_437 EQU 1 ;AN000;VALUE RETURNED DB VAL_437 ;AN000; FOR: DW S437 ;AN000;SPECIFIC CHOICE IF STRING VAL_850 EQU 2 ;AN000;VALUE RETURNED DB VAL_850 ;AN000; FOR: DW S850 ;AN000;SPECIFIC CHOICE IF STRING VAL_860 EQU 3 ;AN000;VALUE RETURNED DB VAL_860 ;AN000; FOR: DW S860 ;AN000;SPECIFIC CHOICE IF STRING VAL_863 EQU 4 ;AN000;VALUE RETURNED DB VAL_863 ;AN000; FOR: DW S863 ;AN000;SPECIFIC CHOICE IF STRING VAL_865 EQU 5 ;AN000;VALUE RETURNED DB VAL_865 ;AN000; FOR: DW S865 ;AN000;SPECIFIC CHOICE IF STRING VAL_QUESTION EQU 6 ;AN000;VALUE RETURNED DB VAL_QUESTION ;AN000; FOR: DW SQU ;AN000;SPECIFIC CHOICE IF STRING ; SET OF ASCIIZ STRINGS, DEFINING THE POSITIONAL PARAMETER S437 DB "437",0 ;AN000;USA S850 DB "850",0 ;AN000;MULTI-LINGUAL S860 DB "860",0 ;AN000;PORTUGUESE S863 DB "863",0 ;AN000;CANADIAN FRENCH S865 DB "865",0 ;AN000;NORDIC SQU DB "?",0 ;AN000; ;RESULTS CONTROL BLOCK FOR THE POSITIONAL PARAMETER, AND SWITCH PARAMETER RESULT LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS DB 3 ;AN000; TYPE RETURNED: 0=RESERVED, ; 1=NUMBER, 2=LIST INDEX, ; 3=STRING, 4=COMPLEX, ; 5=FILESPEC, 6=DRIVE ; 7=DATE, 8=TIME ; 9=QUOTED STRING RESULT_TAG DB 0FFH ;AN000; MATCHED ITEM TAG RESULT_SYN DW 0 ;AN000;POINTER TO SYNONYM RESULT_PTR DD ? ;AN000;OFFSET OF STRING VALUE ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = HEADER ;AN000; ;PARSER CONTROL BLOCK DEFINING THE ONLY SWITCH, OPTIONAL ;THE SWITCH IS "/STA" OR "/STATUS". WHEN REQUESTED, IT MEANS TO IDENTIFY ;WHAT CODEPAGE IS CURRENTLY SUPPORTED BY THE PREVIOUS GRAFTABL, IF ANY. PUBLIC CONTROL_SW ;AN000;LET LINK MAKE THIS ADDRESSABLE CONTROL_SW LABEL BYTE ;AN000;SWITCH DESCRIPTOR FOR /STA DW 0001H ;AN000; CONTROLS TYPE MATCHED ;SELECTED BITS: "OPTIONAL" ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED) ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE ; CHECKED) ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED) ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED) ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED) ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED) ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED) ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED) ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED) ; 0010H=IGNORE ":" AT END IN MATCH ; 0002H=REPEATS ALLOWED ; 0001H=OPTIONAL DW 0000H ;AN000;FUNCTION_FLAGS ("NO CAPS") ; 0001H=CAP RESULT BY FILE TABLE ; 0002H=CAP RESULT BY CHAR TABLE ; 0010H=REMOVE ":" AT END DW RESULT ;AN000; RESULT BUFFER ;(USE SAME RESULT BUF AS DID POSITIONAL PARM) DW NOVALS ;AN000; VALUE LISTS DB 2 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS ; IN FOLLOWING LIST SW_STA DB "/STA",0 ;AN000; IF n >0, KEYWORD 1 SW_STATUS DB "/STATUS",0 ;AN000;SECOND KEYWORD ;VALUE CONTROL BLOCK FOR THE SWITCHES NOVALS LABEL BYTE ;AN000; DB 0 ;AN000; NUMBER OF VALUE DEFINITIONS (0 - 3) ; = = = = = = = = = = = = PATHLABL GRTABPAR ;AN006; HEADER ;AN000; ; $SALUT (4,4,9,36) ;AN000; PARSER PROC NEAR ;AN000; PUBLIC PARSER ;AN000; ;INPUT: "CURRENT_PARM" = OFFSET TO NEXT PARM IN COMMAND STRING ; "ORDINAL" = COUNT OF NEXT PARM TO PARSE ; PSP+81H = TEXT OF DOS COMMAND LINE PARMS STRING ;OUTPUT: IF A CODEPAGE NUMBER WAS SPECIFIED ; BX = OFFSET TO LANGUAGE TABLE TO BE LOADED ; DX = INTEGER VALUE OF CODEPAGE SPECIFIED ; IF /STATUS WAS SPECIFIED ; BX = 0 ; IF QUESTION MARK WAS SPECIFIED ; BX=-1 ;IF THERE WAS ANY PROBLEM WITH THE PARMS, THE QUESTION MARK IS ASSUMED, ;AND "EXITFL" SET TO "EXPAR" TO INDICATE PARM ERROR. ;IT A CP IS SPECIFIED, A STATUS REPORT IS ALWAYS GIVEN TO SAY WHAT WHAT ;THERE PREVIOUSLY, SO IF THE USER SPECIFIED A CP AND THE /STATUS SWITCH, ;THEN THE /STATUS DOES NOTHING BEYOND WHAT WOULD HAVE BEEN DONE ALREADY ;WITH JUST THE CP SPECIFICATION. I ALWAYS REPORT STATUS. THE ONLY ;REASON TO HAVE /STATUS IS TO BE ABLE TO SEE WHAT IS THERE ALREADY ;WITHOUT INVOKING THE DEFAULT OF 437 (USA) BY NOT SPECIFYING A CP. ; = = = = = = = = = = = = ; $SEARCH COMPLEX ;AN000;LOOP THRU COMMAND LINE JMP SHORT $$SS1 $$DO1: ;LOOKING AT RET CODE IN AX SET BY SYSPARSE CMP AX,ZERO ;AN000;WERE THERE ANY ERRORS? ; $EXITIF NE ;AN000;HAD A PROBLEM JE $$IF1 CALL PARSE_ERROR ;AN000;DISPLAY REASON FOR ERROR ; $ORELSE LONG ;AN000;SINCE NO PROBLEM, SO FAR JMP $$SR1 $$IF1: MOV ORDINAL,CX ;AN000;SAVE UPDATED COUNT CMP FIRST_TIME,ZERO ;AN000;DO I HAVE A PARM YET? ; $IF E ;AN000;NOT YET, LOOK AT THIS ONE JUST FOUND JNE $$IF4 MOV CURRENT_PARM,SI ;AN000;REMEMBER HOW FAR I GOT CMP RESULT_SYN,ZERO ;AN000;WAS POSITIONAL PARM SPECIFIED? ; $IF E ;AN000;IF POSITIONAL PARM SPECIFIED, JNE $$IF5 MOV CL,RESULT_TAG ;AN000;GET ID OF SPECIFIED PARM XOR CH,CH ;AN000;CLEAR HIGH BYTE CMP CL,VAL_QUESTION ;AN000;WAS "?" SPECIFIED? ; $IF E ;AN000;IF "?" SPECIFIED JNE $$IF6 MOV BX,RETCODE_QUESTION ;AN000;INDICATE THAT "?" SPECIFIED ; $ELSE ;AN000;SINCE "?" NOT SPECIFIED JMP SHORT $$EN6 $$IF6: LEA BX,TABLEUS ;AN000;GET WHERE FIRST CODEPAGE STARTS, USING CX ; AS A COUNTER, STEP THRU THE LANGUAGE TABLES ; UNTIL GETTING TO THE SPECIFIED ONE ; $DO COMPLEX ;AN000; JMP SHORT $$SD8 $$DO8: ADD BX,TYPE LANGUAGE ;AN000;POINT TO NEXT TABLE ADD ACTIVECPID,CPID_L ;AN000;SELECT NEXT CPID ENTRY ; $STRTDO ;AN000; $$SD8: ; $ENDDO LOOP ;AN000;DECREMENT INDEX LOOP $$DO8 ;BX-OFFSET TO LANGUAGE TABLE ; INDICATED BY POSITIONAL PARM ; $ENDIF ;AN000;"?" SPECIFIED? $$EN6: ; $ELSE ;AN000;SINCE NOT POSITIONAL PARM SPECIFIED JMP SHORT $$EN5 $$IF5: ;RESULT_SYN POINTS TO A SWITCH XOR BX,BX ;AN000; MUST HAVE BEEN THE SWITCH, /STATUS MOV SW_STA,BLANK ;AN002;AVOID THE DUPLICATION OF THIS SWITCH MOV SW_STATUS,BLANK ;AN002;AVOID THE DUPLICATION OF THIS SWITCH ; $ENDIF ;AN000;POSITIONAL? $$EN5: INC FIRST_TIME ;AN000;INDICATE A PARM HAS BEEN FOUND ; $ELSE ;AN000;SINCE ALREADY HAVE A PARM JMP SHORT $$EN4 $$IF4: PUSH SI ;AN003;SAVE NEW INDEX TO COMMAND LINE CALL PARSE_ERROR ;AN000;FUSS ABOUT TOO MANY PARMS POP CURRENT_PARM ;AN000;REMEMBER HOW FAR I GOT ; $ENDIF ;AN000;ALREADY HAVE A PARM? $$EN4: MOV PARSE_RESULT,BX ;AN000;SAVE THE RESULT OF THIS PARSE ; $STRTSRCH ;AN000; $$SS1: LEA DI,PARMS ;AN000; ES:DI = PARSE CONTROL DEFINITON MOV SI,CURRENT_PARM ;AN000; DS:SI = COMMAND STRING, NEXT PARM XOR DX,DX ;AN000; RESERVED, INIT TO ZERO MOV CX,ORDINAL ;AN000; OPERAND ORDINAL, INITIALLY ZERO CALL SYSPARSE ;AN000;LOOK AT DOS PARMS ; AX=EXIT CODE ; BL=TERMINATED DELIMETER CODE ; CX=NEW OPERAND ORDINAL ; SI=SET TO PAST SCANNED OPERAND ; DX=SELECTED RESULT BUFFER CMP AX,SYSPRM_EX_EOL ;AN000; IS THAT THE END OF THE PARMS? ;IF NOT, LOOP BACK AND FIND OUT ; WHAT THAT PARM IS ; $ENDLOOP E ;AN000;END OF LIST JNE $$DO1 CMP FIRST_TIME,ZERO ;AN000;FIND ANYTHING YET? ; $IF E ;AN000;IF NO PARM SPECIFIED JNE $$IF18 LEA BX,TABLEUS ;AN000;SPECIFY 437 (USA) AS DEFAULT ; $ELSE ;AN000;SINCE A PARM WAS FOUND JMP SHORT $$EN18 $$IF18: MOV BX,PARSE_RESULT ;AN000;REMEMBER PARM ALREADY FOUND ; $ENDIF ;AN000; $$EN18: ;BX=-1, "?"; BX=0, "/STATUS";BX>0, CP TABLE CMP BX,ZERO ;AN000;WAS A CP TABLE FOUND? ; $IF A ;AN000;IF A CP TABLE FOUND JNA $$IF21 MOV DX,[BX].LANID ;AN000;FETCH THE TWO CHAR ID FROM TABLE ; $ENDIF ;AN000; $$IF21: ; $ENDSRCH ;AN000;FINISHED WITH DOS COMMAND LINE $$SR1: RET ;AN000;RETURN TO CALLER PARSER ENDP ;AN000; ; = = = = = = = = = = = = ;AN000; HEADER ;AN000; PARSE_ERROR PROC NEAR ;AN000; ;INPUT: "FIRST_TIME" - IF NON-ZERO, FORCE ERROR CODE TO "TOO MANY PARMS" ; AX - ERROR NUMBER RETURNED FROM PARSE. ; SI - OFFSET INTO COMMAND OF FIRST BYTE BEYOND PARM IN ERROR ; "CURRENT_PARM" - OFFSET INTO COMMAND OF WHERE TO START LOOKING FOR PARM ;OUTPUT: APPROPRIATE ERROR MESSAGE IS DISPLAYED. ; BX IS SET TO PRETEND THAT THE "?" WAS SPECIFIED. ; "EXITFL" SET TO "EXPAR" TO INDICATE PARM ERROR. ; = = = = = = = = = = = = CMP FIRST_TIME,ZERO ;AN000;ANY PARMS FOUND YET? ; $IF NE ;AN000;IF PARM ALREADY FOUND JE $$IF24 MOV AX,SYSPRM_EX_MANY ;AN000;CHANGE RETURN CODE TO "TOO MANY PARMS" ; $ENDIF ;AN000;PARMS FOUND? $$IF24: MOV MSGNUM_PARSE,AX ;AN000;PASS MESSAGE NUMBER TO DESCRIPTOR MOV AX,CURRENT_PARM ;AN003;GET POINTER TO START OF BAD PARM CMP SI,AX ;AN003;HAS THE INDEX TO COMMAND LINE MOVED? ; $IF NE ;AN003;YES, THERE IS A FAULTY PARM JE $$IF26 MOV BYTE PTR [SI],NUL ;AN003;DELIMIT THE BAD PARM MOV SUBLIST_PARSE.SUB_VALUE,AX ;AN000;POINT SUBLIST TO BAD PARM MOV MSGNUM_PARSE.MSG_SUBLIST,OFFSET SUBLIST_PARSE ;AN003;POINT TO SUBLIST MOV MSGNUM_PARSE.MSG_COUNT,ONE_SUBS ;AN003;SET COUNT OF SUBLISTS TO ONE ; $ENDIF ;AN003;INDEX MOVED? $$IF26: LEA DI,MSGNUM_PARSE ;AN000;PASS MESSAGE DESCRIPTOR CALL SENDMSG ;AN000;DISPLAY ERROR MESSAGE MOV BX,RETCODE_QUESTION ;AN000;INDICATE THAT "?" SPECIFIED MOV EXITFL,EXPAR ;AN000;ERRORLEVEL CODE TO "PARM ERROR" RET ;AN000;RETURN TO CALLER PARSE_ERROR ENDP ;AN000; ; = = = = = = = = = = = = PATHLABL GRTABPAR ;AN006; CSEG ENDS ;AN000; END ;AN000;