MODULE RNOVMS ( IDENT = 'X00.06', %TITLE 'RNOVMS - RUNOFF VMS Command Line Interface' MAIN = RNOVMS, ! Entry point of main program ADDRESSING_MODE( EXTERNAL=LONG_RELATIVE ) ) = BEGIN ! ! COPYRIGHT (c) 1980 BY ! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ! ! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ! ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE ! INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ! COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ! OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ! TRANSFERRED. ! ! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ! AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ! CORPORATION. ! ! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. ! !++ ! ! FACILITY: BLISS Library ! ! ABSTRACT: ! ! This module is the RUNOFF VMS Command Line interface module. ! ! ENVIRONMENT: User Mode ! ! AUTHOR: Ward Clark, CREATION DATE: 21 May 1979 ! !-- ! ! TABLE OF CONTENTS: ! FORWARD ROUTINE rnovms, ! RUNOFF VMS command interface routine debug_parse : NOVALUE, ! /DEBUG qualifier value parse routine messages_parse : NOVALUE, ! /MESSAGES qualifier value parse routine underline_parse : NOVALUE; ! /UNDERLINE qualifier value parse routine ! ! INCLUDE FILES: ! LIBRARY 'BLI:XPORT' ; ! XPORT macro and field definitions REQUIRE 'RNOMAC' ; ! RUNOFF macro and field definitions undeclare %quote $descriptor; LIBRARY 'SYS$LIBRARY:CLIMAC' ; ! VMS DCL CLI interface macros LIBRARY 'SYS$LIBRARY:STARLET' ; ! and symbol definitions ! ! MACROS: ! ! ! EQUATED SYMBOLS: ! LITERAL yes = 1, ! Used to turn indicators on no = 0; ! Used to turn indicators off ! ! OWN STORAGE: ! ! See below ! ! EXTERNAL REFERENCES: ! EXTERNAL ROUTINE RUNOFF, ! Transportable RUNOFF entry point XPO$CHAR_PARSE, ! XPORT character value parse routine XPO$SHORT_PARSE, ! XPORT short integer parse routine XPO$STR_PARSE, ! XPORT string parse routine XPO$CLI_ERROR, ! XPORT DCL error routine LIB$LOOKUP_KEY : ADDRESSING_MODE(GENERAL); ! VMS OTS keyword lookup routine EXTERNAL XPO$CLI_WORK; ! DCL CLI "work area" - life-of-image control block %TITLE 'RUNOFF DCL CLI Control Blocks and Work Areas' OWN runoff_command : $RNO_CMD; ! RUNOFF command information block $CLIQUALCODES( RUNOFF, ! Define the RUNOFF qualifier codes BACKSPACE, BOLD, CHANGE_BARS, DEBUG, DOWN, FORM_SIZE, MESSAGES, OVERPRINT, PAGES, PAUSE, RIGHT, SEQUENCE, SIMULATE, UNDERLINE, VARIANT ); $LITERAL backspace_bit = $DISTINCT, bold_bit = $DISTINCT, change_bars_bit = $DISTINCT, contents_bit = $DISTINCT, debug_bit = $DISTINCT, down_bit = $DISTINCT, form_size_bit = $DISTINCT, index_bit = $DISTINCT, messages_bit = $DISTINCT, overprint_bit = $DISTINCT, pages_bit = $DISTINCT, pause_bit = $DISTINCT, right_bit = $DISTINCT, sequence_bit = $DISTINCT, simulate_bit = $DISTINCT, underline_bit = $DISTINCT, variant_bit = $DISTINCT, max_qual_bit = $DISTINCT - 1; OWN runoff_qual : BITVECTOR[ max_qual_bit+1 ] PRESET( [underline_bit] = yes ); ! ! Command Qualifier Descriptors ! OWN backspace_qual : $CLIQUALDESC( QDCODE = BACKSPACE, SETLST = backspace_bit ), bold_qual : $CLIQUALDESC( QDCODE = BOLD, SETLST = bold_bit, TRUACT = XPO$SHORT_PARSE, USRVAL = runoff_command[RNO$H_BOLD] ), change_bar_qual : $CLIQUALDESC( QDCODE = CHANGE_BARS, SETLST = change_bars_bit, TRUACT = XPO$CHAR_PARSE, USRVAL = runoff_command[RNO$C_CHANGE] ), debug_qual : $CLIQUALDESC( QDCODE = DEBUG, SETLST = debug_bit, TRUACT = debug_parse ), down_qual : $CLIQUALDESC( QDCODE = DOWN, SETLST = down_bit, TRUACT = XPO$SHORT_PARSE, USRVAL = runoff_command[RNO$H_DOWN] ), form_size_qual : $CLIQUALDESC( QDCODE = FORM_SIZE, SETLST = form_size_bit, TRUACT = XPO$SHORT_PARSE, USRVAL = runoff_command[RNO$H_FORM_SIZE] ), messages_qual : $CLIQUALDESC( QDCODE = MESSAGES, SETLST = messages_bit, TRUACT = messages_parse ), overprint_qual : $CLIQUALDESC( QDCODE = OVERPRINT, SETLST = overprint_bit ), pages_qual : $CLIQUALDESC( QDCODE = PAGES, SETLST = pages_bit, TRUACT = XPO$STR_PARSE, USRVAL = runoff_command[RNO$T_PAGES] ), pause_qual : $CLIQUALDESC( QDCODE = PAUSE, SETLST = pause_bit ), right_qual : $CLIQUALDESC( QDCODE = RIGHT, SETLST = right_bit, TRUACT = XPO$SHORT_PARSE, USRVAL = runoff_command[RNO$H_RIGHT] ), sequence_qual : $CLIQUALDESC( QDCODE = SEQUENCE, SETLST = sequence_bit ), simulate_qual : $CLIQUALDESC( QDCODE = SIMULATE, SETLST = simulate_bit ), underline_qual : $CLIQUALDESC( QDCODE = UNDERLINE, SETLST = underline_bit, TRUACT = underline_parse, USRVAL = runoff_command[RNO$C_UNDERLINE] ), variant_qual : $CLIQUALDESC( QDCODE = VARIANT, SETLST = variant_bit, TRUACT = XPO$STR_PARSE, USRVAL = runoff_command[RNO$T_VARIANT] ), end_of_qual : $CLIQUALEND, ! ! VMS DCL Command Language Interpreter control blocks and work areas ! initial_desc : ! CLI initialization descriptor: $CLIREQDESC( RQTYPE = INITPRS, ! initialization indicator RQFLGS = ABSADR, ! absolute address indicator ERRACT = XPO$CLI_ERROR ), ! address of error action routine command_desc : ! Command qualifiers request descriptor: $CLIREQDESC( RQTYPE = GETQUAL, ! command-level qualifiers request RQFLGS = ABSADR, ! absolute address indicator ERRACT = XPO$CLI_ERROR, ! address of error action routine QUALST = backspace_qual ), ! address of qualifier descriptors input_file_desc : ! Input file request descriptor: $CLIREQDESC( RQTYPE = INPUT1, ! primary input indicator RQFLGS = ABSADR, ! absolute address indicator ERRACT = XPO$CLI_ERROR, ! address of error action routine QUALST = 0 ), ! address of qualifier descriptors (none) output_desc : ! Output file request descriptor: $CLIREQDESC( RQTYPE = OUTPUT1, ! primary output indicator RQFLGS = ABSADR, ! absolute address indicator ERRACT = XPO$CLI_ERROR, ! address of error action routine QUALST = 0 ), ! address of qualifier descriptors (none) contents_desc : ! Table-of-contents file request descriptor: $CLIREQDESC( RQTYPE = OUTPUT2, ! secondary output indicator RQFLGS = ABSADR, ! absolute address indicator BITNUM = contents_bit, ! runoff_qual bit to set ERRACT = XPO$CLI_ERROR, ! address of error action routine QUALST = 0 ), ! address of qualifier descriptors (none) index_desc : ! Binary-index file request descriptor: $CLIREQDESC( RQTYPE = OUTPUT3, ! tertiary output indicator RQFLGS = ABSADR, ! absolute address indicator BITNUM = index_bit, ! runoff_qual bit to set ERRACT = XPO$CLI_ERROR, ! address of error action routine QUALST = 0 ), ! address of qualifier descriptors (none) end_of_cmd_desc : ! Parameter "cleanup" request descriptor: $CLIREQDESC( RQTYPE = ENDPRM1, ! parameter cleanup indicator RQFLGS = ABSADR, ! absolute address indicator ERRACT = XPO$CLI_ERROR ), ! address of error action routine str_parse_desc : ! ASCII string value parse request descriptor: $CLIREQDESC( RQTYPE = ASCIIVAL, ! ASCII string value parse indicator RQFLGS = ABSADR, ! absolute address indicator ERRACT = XPO$CLI_ERROR ); ! address of error action routine GLOBAL ROUTINE rnovms = %TITLE 'RNOVMS - Primary RUNOFF CLI Interface Routine' !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine uses the VMS DCL CLI routines to obtain command ! line information which is in turn passed to the RUNOFF application ! in a transportable manner. ! ! FORMAL PARAMETERS: ! ! None ! ! IMPLICIT INPUTS: ! ! None ! ! IMPLICIT OUTPUTS: ! ! None ! ! COMPLETION CODES: ! ! completion code from RUNOFF ! ! SIDE EFFECTS: ! ! None ! !-- BEGIN BUILTIN AP; ! Declare the name of the argument pointer LOCAL status; ! Temporary routine completion code ! ! Initialize the VMS DCL CLI facility. ! $XPO_CALL_CLI( initial_desc, XPO$CLI_WORK, runoff_qual ); ! ! Initialize the RUNOFF command block. ! DO BEGIN BEGIN MAP runoff_command : VECTOR; INCR index FROM 0 TO RNO$K_CMD_LEN / %UPVAL - 1 DO runoff_command[.index] = 0; END; runoff_command[RNO$C_CHANGE] = %X'FF'; runoff_command[RNO$C_UNDERLINE] = %X'FF'; ! ! Process all RUNOFF command qualifiers. ! $XPO_CALL_CLI( command_desc, XPO$CLI_WORK, runoff_qual ); ! ! Process each set of input and output parameters. ! $XPO_CALL_CLI( input_file_desc, XPO$CLI_WORK, runoff_qual ); $XPO_CALL_CLI( output_desc, XPO$CLI_WORK, runoff_qual ); $XPO_CALL_CLI( contents_desc, XPO$CLI_WORK, runoff_qual ); $XPO_CALL_CLI( index_desc, XPO$CLI_WORK, runoff_qual ); $XPO_CALL_CLI( end_of_cmd_desc, XPO$CLI_WORK, runoff_qual ); ! ! Complete the RUNOFF command block (RNOCMD) from the information returned by the DCL CLI. ! NOTE : Some RNOCMD fields are set by qualifier action routines. ! $STR_DESC_INIT( DESCRIPTOR = runoff_command[RNO$T_INPUT], STRING = ( .input_file_desc[CLI$W_RQSIZE], .input_file_desc[CLI$A_RQADDR] ) ); $STR_DESC_INIT( DESCRIPTOR = runoff_command[RNO$T_OUTPUT], STRING = ( .output_desc[CLI$W_RQSIZE], .output_desc[CLI$A_RQADDR] ) ); $STR_DESC_INIT( DESCRIPTOR = runoff_command[RNO$T_CONTENTS], STRING = ( .contents_desc[CLI$W_RQSIZE], .contents_desc[CLI$A_RQADDR] ) ); $STR_DESC_INIT( DESCRIPTOR = runoff_command[RNO$T_INDEX], STRING = ( .index_desc[CLI$W_RQSIZE], .index_desc[CLI$A_RQADDR] ) ); runoff_command[RNO$V_BACKSPACE] = .runoff_qual[backspace_bit]; runoff_command[RNO$V_CHANGE] = .runoff_qual[change_bars_bit]; runoff_command[RNO$V_CONTENTS] = .runoff_qual[contents_bit]; runoff_command[RNO$V_INDEX] = .runoff_qual[index_bit]; runoff_command[RNO$V_OVERPRINT] = .runoff_qual[overprint_bit]; runoff_command[RNO$V_PAUSE] = .runoff_qual[pause_bit]; runoff_command[RNO$V_SEQUENCE] = .runoff_qual[sequence_bit]; runoff_command[RNO$V_SIMULATE] = .runoff_qual[simulate_bit]; runoff_command[RNO$V_UNDERLINE] = .runoff_qual[underline_bit]; IF .runoff_command[RNO$C_CHANGE] EQLU %X'FF' THEN runoff_command[RNO$C_CHANGE] = 0 ELSE runoff_command[RNO$V_CHNG_CHAR] = yes; IF .runoff_command[RNO$C_UNDERLINE] EQLU %X'FF' THEN runoff_command[RNO$C_UNDERLINE] = 0 ELSE runoff_command[RNO$V_UND_CHAR] = yes; ! ! Call the RUNOFF application to process a single command line. ! status = RUNOFF( runoff_command ); ! Pass the RUNOFF application the address ! of the complete command information block. IF NOT .status ! If RUNOFF returns a failure completion code, THEN ! EXITLOOP ! exit the input file-spec processing loop. END WHILE .end_of_cmd_desc[CLI$V_MOREINP]; ! Otherwise, loop until all input file-spec ! have been processed. ! ! Return to the system. ! RETURN .status ! Return the final RUNOFF completion code to the caller. END; %TITLE 'RNOVMS - /DEBUG Qualifier Value Parse' ROUTINE debug_parse ( qualifier_desc ) : NOVALUE = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine parses a /DEBUG qualifier value. ! ! FORMAL PARAMETERS: ! ! qualifier_desc.r.r - address of a qualifier descriptor ! ! IMPLICIT INPUTS: ! ! None ! ! IMPLICIT OUTPUTS: ! ! runoff_command - /DEBUG keyword indicators set ! ! ROUTINE VALUE: ! ! None ! ! SIDE EFFECTS: ! ! None ! !-- BEGIN MAP qualifier_desc : REF BLOCK[,BYTE]; ! Redefine the qualifier descriptor parameter OWN debug_keys : ! /DEBUG keyword table $XPO_KEY_TABLE( (CONDITIONALS,1), (CONTENTS,2), (FILES,3), (INDEX,4), (ALL,5) ); LOCAL qual_value_desc : VECTOR[2], ! Qualifier value descriptor before parsing keyword_value, ! Keyword value area status; ! Temporary routine completion code ! ! Setup a qualifier value descriptor for error messages. ! qual_value_desc[0] = ! Setup a qualifier value descriptor for error messages. .qualifier_desc[CLI$W_QDVALSIZ]; qual_value_desc[1] = .qualifier_desc[CLI$A_QDVALADR]; ! ! Process one qualifier keyword at a time. ! DO ! Loop until all values have been processed. BEGIN $XPO_CALL_CLI( str_parse_desc, XPO$CLI_WORK, .qualifier_desc ); ! ! Verify that a valid keyword was specified. ! status = LIB$LOOKUP_KEY( ! Call the keyword lookup routine with the following arguments: str_parse_desc[CLI$Q_RQDESC], ! address of the keyword descriptor debug_keys, ! address of the /DEBUG keyword table keyword_value ); ! address of keyword value deposit area IF NOT .status THEN SIGNAL_STOP( CLI$_SYNTAX,1,qual_value_desc, .status,1,str_parse_desc[CLI$Q_RQDESC] ); ! ! Record the specified keyword in the RUNOFF command block. ! CASE .keyword_value FROM 1 TO 5 OF SET [ 1 ] : runoff_command[RNO$V_DEB_COND] = yes; [ 2 ] : runoff_command[RNO$V_DEB_CONT] = yes; [ 3 ] : runoff_command[RNO$V_DEB_FILES] = yes; [ 4 ] : runoff_command[RNO$V_DEB_INDEX] = yes; [ 5 ] : BEGIN runoff_command[RNO$V_DEB_COND] = yes; runoff_command[RNO$V_DEB_CONT] = yes; runoff_command[RNO$V_DEB_FILES] = yes; runoff_command[RNO$V_DEB_INDEX] = yes; END; TES; END WHILE .str_parse_desc[CLI$V_MOREVALS]; ! Loop until all keywords have been processed. ! ! Return to the DCL CLI. ! RETURN END; %TITLE 'RNOVMS - /MESSAGES Qualifier Value Parse' ROUTINE messages_parse ( qualifier_desc ) : NOVALUE = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine parses a /MESSAGES qualifier value. ! ! FORMAL PARAMETERS: ! ! qualifier_desc.r.r - address of a qualifier descriptor ! ! IMPLICIT INPUTS: ! ! None ! ! IMPLICIT OUTPUTS: ! ! runoff_command - /MESSAGES keyword indicators set ! ! ROUTINE VALUE: ! ! None ! ! SIDE EFFECTS: ! ! None ! !-- BEGIN MAP qualifier_desc : REF BLOCK[,BYTE]; ! Redefine the qualifier descriptor parameter OWN messages_keys : ! /MESSAGES keyword table $XPO_KEY_TABLE( (USER,1), (OUTPUT,2) ); LOCAL qual_value_desc : VECTOR[2], ! Qualifier value descriptor before parsing keyword_value, ! Keyword value area status; ! Temporary routine completion code ! ! Setup a qualifier value descriptor for error messages. ! qual_value_desc[0] = ! Setup a qualifier value descriptor for error messages. .qualifier_desc[CLI$W_QDVALSIZ]; qual_value_desc[1] = .qualifier_desc[CLI$A_QDVALADR]; ! ! Process one qualifier keyword at a time. ! DO ! Loop until all values have been processed. BEGIN $XPO_CALL_CLI( str_parse_desc, XPO$CLI_WORK, .qualifier_desc ); ! ! Verify that a valid keyword was specified. ! status = LIB$LOOKUP_KEY( ! Call the keyword lookup routine with the following arguments: str_parse_desc[CLI$Q_RQDESC], ! address of the keyword descriptor messages_keys, ! address of the /MESSAGES keyword table keyword_value ); ! address of keyword value deposit area IF NOT .status THEN SIGNAL_STOP( CLI$_SYNTAX,1,qual_value_desc, .status,1,str_parse_desc[CLI$Q_RQDESC] ); ! ! Record the specified keyword in the RUNOFF command block. ! CASE .keyword_value FROM 1 TO 2 OF SET [ 1 ] : runoff_command[RNO$V_MSG_USER] = yes; [ 2 ] : runoff_command[RNO$V_MSG_OUT] = yes; TES; END WHILE .str_parse_desc[CLI$V_MOREVALS]; ! Loop until all keywords have been processed. ! ! Return to the DCL CLI. ! RETURN END; %TITLE 'RNOVMS - /UNDERLINE Qualifier Value Parse' ROUTINE underline_parse ( qualifier_desc ) : NOVALUE = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine parses a /UNDERLINE qualifier value. ! ! FORMAL PARAMETERS: ! ! qualifier_desc.r.r - address of a qualifier descriptor ! ! IMPLICIT INPUTS: ! ! None ! ! IMPLICIT OUTPUTS: ! ! runoff_command - /UNDERLINE keyword indicators/value set ! ! ROUTINE VALUE: ! ! None ! ! SIDE EFFECTS: ! ! None ! !-- BEGIN MAP qualifier_desc : REF BLOCK[,BYTE]; ! Redefine the qualifier descriptor parameter OWN underline_keys : ! /UNDERLINE keyword table $XPO_KEY_TABLE( (NONSPACING,1), (SEPARATE,2) ); LOCAL qual_value_desc : VECTOR[2], ! Qualifier value descriptor before parsing keyword_value, ! Keyword value area status, ! Temporary routine completion code first_character; ! Single character ! ! Setup a qualifier value descriptor for error messages. ! qual_value_desc[0] = ! Setup a qualifier value descriptor for error messages. .qualifier_desc[CLI$W_QDVALSIZ]; qual_value_desc[1] = .qualifier_desc[CLI$A_QDVALADR]; ! ! Process one qualifier value at a time. ! DO ! Loop until all values have been processed. ! ! Parse a character value of the form "c", 123, %O377 or %X01FF. ! IF CH$RCHAR( .qualifier_desc[CLI$A_QDVALADR] ) ! If the 1st character of the value is LSSU %C'A' OR ! not an upper case letter, CH$RCHAR( .qualifier_desc[CLI$A_QDVALADR] ) ! GTRU %C'Z' ! THEN ! XPO$CHAR_PARSE( .qualifier_desc ) ! convert and store the character. ! ! Get a qualifier keyword from the DCL CLI. ! ELSE BEGIN $XPO_CALL_CLI( str_parse_desc, XPO$CLI_WORK, .qualifier_desc ); ! ! Verify that a valid keyword was specified. ! status = LIB$LOOKUP_KEY( ! Call the keyword lookup routine with the following arguments: str_parse_desc[CLI$Q_RQDESC], ! address of the keyword descriptor underline_keys, ! address of the /UNDERLINE keyword table keyword_value ); ! address of keyword value deposit area IF NOT .status THEN SIGNAL_STOP( CLI$_SYNTAX,1,qual_value_desc, .status,1,str_parse_desc[CLI$Q_RQDESC] ); ! ! Record the specified keyword in the RUNOFF command block. ! CASE .keyword_value FROM 1 TO 2 OF SET [ 1 ] : runoff_command[RNO$V_UND_NONSP] = yes; [ 2 ] : runoff_command[RNO$V_UND_SEPAR] = yes; TES; END WHILE .str_parse_desc[CLI$V_MOREVALS]; ! Loop until all keywords have been processed. ! ! Return to the DCL CLI. ! RETURN END; END ELUDOM