MODULE RNOT10 ( IDENT = 'X00.08', %TITLE 'RUNOFF TOPS-10 Command Line Interface' MAIN = RNOT10 ) = BEGIN ! ! COPYRIGHT (c) 1979 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-36 Library ! ! ABSTRACT: ! ! This module is the RUNOFF TOPS-10 Command Line interface module. ! ! ENVIRONMENT: User Mode ! ! AUTHOR: Ward Clark, CREATION DATE: 8 August 1978 ! !-- ! ! INCLUDE FILES: ! LIBRARY 'BLI:XPORT' ; ! XPORT macro and field definitions REQUIRE 'BLI:X10SCN' ; ! TOPS-10 SCAN macro and field definitions REQUIRE 'RNOMAC' ; ! RUNOFF macro and field definitions ! ! TABLE OF CONTENTS: ! FORWARD ROUTINE RNOT10, ! RUNOFF TOPS-10 command interface routine CLEAR_RESULTS : NOVALUE, ! SCAN "clear results" action routine ALL_INPUT : NOVALUE, ! SCAN "allocate input" action routine ALL_OUTPUT : NOVALUE, ! SCAN "allocate output" action routine STORE_VALUE : $SCAN_G12 NOVALUE, ! SCAN "store switch value" action routine CHANGE_PARSE : $SCAN_G78 NOVALUE, ! /CHANGE switch value parsing routine DEBUG_PARSE : $SCAN_G78 NOVALUE, ! /DEBUG switch value parsing routine UNDER_PARSE : $SCAN_G78 NOVALUE, ! /UNDERLINE switch value parsing routine GET_CHAR_VALUE : $SCAN_G78 NOVALUE; ! Common /CHANGE and /UNDERLINE character parsing routine ! ! EXTERNAL REFERENCES: ! EXTERNAL X10$EXIT_FLAG; ! Program exit flag for X10$RETURN EXTERNAL ROUTINE SCAN$ISCAN : $SCAN_P1_T1234 NOVALUE, ! SCAN initialization SCAN$TSCAN : $SCAN_P1_T1234 NOVALUE, ! Traditional SCAN SCAN$OSCAN : $SCAN_P1_T1234 NOVALUE, ! Options SCAN SCAN$NAME : $SCAN_G178_T234 NOVALUE, ! SCAN keyword lookup routine SCAN$OCTNC : $SCAN_G78 NOVALUE, ! SCAN octal number routine SCAN$SIXSC : $SCAN_G78_T1 NOVALUE, ! SCAN keyword parse routine SCAN$SIXSW : $SCAN_G78_T1 NOVALUE, ! SCAN keyword parse routine SCAN$TIAUC : $SCAN_G78 NOVALUE, ! SCAN get character routine SCAN$TISQT : $SCAN_G78 NOVALUE, ! SCAN quoted character routine SCAN$SWASQ, ! SCAN quoted ASCII string scanner SCAN$SWDEC, ! SCAN decimal number scanner SCAN$SWFIL, ! SCAN file-spec scanner X10$RETURN, ! XPORT/SCAN exit to monitor routine X10$SCAN_SPEC, ! XPORT/SCAN File Specification Area decoder RUNOFF; ! Transportable RUNOFF entry point ! ! MACROS: ! MACRO SKIP_RETURN = ! TOPS-10 "skip return" BEGIN BIND RETURN_PC = dummy + 1; ! Point to return PC on the stack RETURN_PC = .RETURN_PC + 1; ! Increment the return PC RETURN; ! to perform a "skip return" to the caller. END %; ! ! EQUATED SYMBOLS: ! LITERAL yes = 1, ! Used to turn indicators on no = 0, ! Used to turn indicators off max_file_spec = 7 + 15 + 6 + 4, ! Maximum length of a TOPS-10 file specification ! (device + directory + file name + file extension) max_quoted_str = 30, ! Maximum length of a SCAN quoted ASCII string max_page_str = 100, ! Maximum length of a /PAGES string max_variant_str = 100, ! Maximum length of a /VARIANT string mx_contents = SCAN$K_FXLEN, ! Length of /CONTENTS SCAN file-spec area mx_index = SCAN$K_FXLEN; ! Length of /INDEX SCAN file-spec area $LITERAL ! SCAN_RESULT vector index and default definitions: backspace = 0, ! /BACKSPACE bold = $DISTINCT, ! /BOLD pd_bold = 1, ! default value mx_bold = 999, ! maximum value change = $DISTINCT, ! /CHANGE pd_change = %C'|', ! default value mx_change = %O'177', ! maximum value debug = $DISTINCT, ! /DEBUG pd_debug = 1, ! default value mx_debug = 1, ! maximum value down = $DISTINCT, ! /DOWN pd_down = 5, ! default value mx_down = 60, ! maximum value draft = $DISTINCT, ! /DRAFT - obsolete - included for compatibility formsize = $DISTINCT, ! /FORMSIZE pd_formsize = 66, ! default value mx_formsize = 999, ! maximum value overprint = $DISTINCT, ! /OVERPRINT pause = $DISTINCT, ! /PAUSE right = $DISTINCT, ! /RIGHT pd_right = 5, ! default value mx_right = 70, ! maximum value sequence = $DISTINCT, ! /SEQUENCE simulate = $DISTINCT, ! /SIMULATE underline = $DISTINCT, ! /UNDERLINE pd_underline = %C'_', ! default value mx_underline = %O'177', ! maximum value max_switch_code = $DISTINCT - 1; ! maximum switch code value $LITERAL ! STORE_VALUE switch codes: pages = 0, ! /PAGES variant = $DISTINCT; ! /VARIANT ! ! OWN STORAGE: ! OWN scan_result : VECTOR[max_switch_code+1], ! General RUNOFF switch table (see above) input_scan_spec : $SCAN_SPEC_INFO, ! Input SCAN file-spec area list_scan_spec : $SCAN_SPEC_INFO, ! Listing SCAN file-spec area toc_scan_spec : $SCAN_SPEC_INFO, ! /CONTENTS SCAN file-spec area index_scan_spec : $SCAN_SPEC_INFO; ! /INDEX SCAN file-spec area $SCAN_TABLE( rno_switches, ! RUNOFF SCAN tables $SCAN_SN( SWITCH = 'BACKSPACE', RESULT = scan_result[backspace], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SP( SWITCH = 'BOLD', PROCESSOR = SCAN$SWDEC, RESULT = scan_result[bold], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SP( SWITCH = 'CHANGE', PROCESSOR = CHANGE_PARSE, RESULT = scan_result[change], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SP( SWITCH = 'CONTENTS', PROCESSOR = SCAN$SWFIL, RESULT = toc_scan_spec, FLAGS = FS_NFS ), $SCAN_SP( SWITCH = 'DEBUG', PROCESSOR = DEBUG_PARSE, RESULT = scan_result[debug], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SP( SWITCH = 'DOWN', PROCESSOR = SCAN$SWDEC, RESULT = scan_result[down], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SN( SWITCH = 'DRAFT', ! Obsolete keyword - included for compatibility RESULT = scan_result[draft], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SP( SWITCH = 'FORMSIZE', PROCESSOR = SCAN$SWDEC, RESULT = scan_result[formsize], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SP( SWITCH = 'INDEX', PROCESSOR = SCAN$SWFIL, RESULT = index_scan_spec, FLAGS = FS_NFS ), $SCAN_SS( SWITCH = 'NOBOLD', RESULT = scan_result[bold], VALUE = 0, FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SS( SWITCH = 'NOCHANGE', RESULT = scan_result[change], VALUE = 0, FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SS( SWITCH = 'NODEBUG', RESULT = scan_result[debug], VALUE = 0, FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SS( SWITCH = 'NOUNDERLINE', RESULT = scan_result[underline], VALUE = 0, FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SN( SWITCH = 'OVERPRINT', RESULT = scan_result[overprint], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SP( SWITCH = 'PAGES', PROCESSOR = SCAN$SWASQ, RESULT = pages, FLAGS = (FS_VRQ, FS_NFS) ), $SCAN_SN( SWITCH = 'PAUSE', RESULT = scan_result[pause], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SP( SWITCH = 'RIGHT', PROCESSOR = SCAN$SWDEC, RESULT = scan_result[right], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SN( SWITCH = 'SEQUENCE', RESULT = scan_result[sequence], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SN( SWITCH = 'SIMULATE', RESULT = scan_result[simulate], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SP( SWITCH = 'UNDERLINE', PROCESSOR = UNDER_PARSE, RESULT = scan_result[underline], FLAGS = (FS_NUE, FS_NFS) ), $SCAN_SP( SWITCH = 'VARIANT', PROCESSOR = SCAN$SWASQ, RESULT = variant, FLAGS = (FS_VRQ, FS_NFS) ) ) $SCAN_KEYS( DEBUG, (ALL, CONDITIONALS, CONTENTS, FILES, INDEX ) ) LITERAL ! Define indices into keyword table: deb_all_key = 0, ! ALL deb_cond_key = 1, ! CONDITIONALS deb_cont_key = 2, ! CONTENTS deb_files_key = 3, ! FILES deb_index_key = 4, ! INDEX max_deb_key = 4; ! maximum keyword index $SCAN_KEYS( UNDERLINE, ( NONSPACING, SEPARATE ) ) LITERAL ! Define indices to keyword table: und_nonsp_key = 0, ! NONSPACING und_separ_key = 1, ! SEPARATE max_und_key = 1; ! maximum keyword index OWN ccl_mode, ! CCL mode set during initialization iscan_list : $ISCAN_LIST( ! SCAN Initialization parameter list COMMAND_LIST = (1, UPLIT( %SIXBIT'RUNOFF' ) ), CCL_NAME = %SIXBIT' RNO', CCL_OFFSET = ccl_mode, MONITOR_RETURN = X10$RETURN ), tscan_list : $TSCAN_LIST( ! Traditional SCAN parameter list: SWITCH_TABLE = rno_switches, ! address of switch description table HELP_ROUTINE = -1, ! use job table for HELP CLEAR_ALL = CLEAR_RESULTS, ! address of "clear all answers" routine INPUT_AREA = ALL_INPUT, ! address of routine to allocate input file-spec area OUTPUT_AREA = ALL_OUTPUT, ! address of routine to allocate output file-spec area STORE_VALUES = STORE_VALUE ), ! address of routine to store switch values oscan_list : $OSCAN_LIST( ! Option SCAN parameter list: SWITCH_TABLE = rno_switches ), ! address of switch description table runoff_command : $RNO_CMD, ! RUNOFF command information block input_file_spec : ! Space to reconstruct the input file-spec VECTOR[ CH$ALLOCATION( max_file_spec ) ], list_file_spec : ! Space to reconstruct the output file-spec VECTOR[ CH$ALLOCATION( max_file_spec ) ], toc_file_spec : ! Space for a /CONTENTS file-spec VECTOR[ CH$ALLOCATION( max_file_spec ) ], index_file_spec : ! Space for a /INDEX file-spec VECTOR[ CH$ALLOCATION( max_file_spec ) ], pages_string : ! Space for a /PAGES value string VECTOR[ CH$ALLOCATION( max_page_str ) ], variant_string : ! Space for a /VARIANT value string VECTOR[ CH$ALLOCATION( max_variant_str ) ]; ! ! EXTERNAL REFERENCES: ! ! ! The external routines which would normally be defined here ! appear after the INCLUDE FILES section above. ! EXTERNAL SCAN$QUOTE, ! SCAN quoted string indicator SCAN$NMUL, ! SCAN internal ASCII string buffer SCAN$NMUE, ! End of SCAN internal ASCII string buffer SCAN$TFCHR, SCAN$LASWD; GLOBAL ROUTINE RNOT10( P1, P2, P3, P4, CCL_OFFSET ) = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine uses the TOPS-10 SCAN routines to obtain command ! line information which is in turn passed to the RUNOFF application ! in a transportable manner. ! ! FORMAL PARAMETERS: ! ! 4 unused parameters ! CCL_OFFSET - CCL mode indicator ( 0 = no arguments, 1 = arguments ) ! ! IMPLICIT INPUTS: ! ! None ! ! IMPLICIT OUTPUTS: ! ! None ! ! COMPLETION CODES: ! ! Normal Completion (1) ! ! SIDE EFFECTS: ! ! None ! !-- BEGIN LOCAL status; ! Temporary completion code ! ! Initialize the TOPS-10 SCAN facility. ! ccl_mode = .CCL_OFFSET; ! Move the CCL indicator into an area ! pointed to by ISCAN_LIST. X10$EXIT_FLAG = NOT (.ccl_mode EQL 0); ! Setup exit indicator for X10$RETURN. SCAN$ISCAN( .iscan_list ); ! Initialize the SCAN facility. ! ! Process a single command line. ! WHILE 1 DO ! Setup to process multiple commands. BEGIN SCAN$TSCAN( .tscan_list ); ! Perform a "traditional" command scan. ! ! Add SWITCH.INI options information to the current command information. ! IF .input_scan_spec[SCAN$C_FXDEV] NEQ 0 ! If the command line is non-null, THEN ! BEGIN ! SCAN$OSCAN( .oscan_list ); ! add SWITCH.INI option information, if any. ! ! Build a RUNOFF command block (RNOCMD) from the information returned by SCAN. ! $STR_DESC_INIT( ! Setup the input file-spec descriptor. DESCRIPTOR = runoff_command[RNO$T_INPUT], STRING = ( X10$SCAN_SPEC(input_scan_spec,input_file_spec), CH$PTR(input_file_spec) ) ); $STR_DESC_INIT( ! Setup the listing file-spec descriptor. DESCRIPTOR = runoff_command[RNO$T_LISTING], STRING = ( X10$SCAN_SPEC(list_scan_spec,list_file_spec), CH$PTR(list_file_spec) ) ); $STR_DESC_INIT( ! Setup the /CONTENTS file-spec descriptor. DESCRIPTOR = runoff_command[RNO$T_CONTENTS], STRING = ( X10$SCAN_SPEC(toc_scan_spec,toc_file_spec), CH$PTR(toc_file_spec) ) ); $STR_DESC_INIT( ! Setup the /INDEX file-spec descriptor. DESCRIPTOR = runoff_command[RNO$T_INDEX], STRING = ( X10$SCAN_SPEC(index_scan_spec,index_file_spec), CH$PTR(index_file_spec) ) ); IF .scan_result[backspace] EQL 1 ! If /BACKSPACE was specified, THEN ! runoff_command[RNO$V_BACKSPACE] = yes; ! indicate so in the command block. IF .scan_result[bold] NEQ -1 ! If /BOLD was specified, THEN ! runoff_command[RNO$G_BOLD] = ! put the "bold" count in the command block. .scan_result[bold]; ! IF .scan_result[change] GTR 0 ! If /CHANGE was specified, THEN ! indicate the following: BEGIN ! runoff_command[RNO$V_CHANGE] = yes; ! /CHANGE specified runoff_command[RNO$V_CHNG_CHAR] = yes; ! change bar character provided runoff_command[RNO$C_CHANGE] = ! actual change bar character .scan_result[change]; ! END; IF .scan_result[down] NEQ -1 ! If /DOWN was specified, THEN ! runoff_command[RNO$G_DOWN] = ! put the "down" count in the command block. .scan_result[down]; ! IF .scan_result[debug] EQL 1 OR ! If /DEBUG or /DRAFT was specified, .scan_result[draft] EQL 1 ! THEN ! BEGIN ! runoff_command[RNO$V_DEB_COND] = yes; ! turn on all /DEBUG indicators. runoff_command[RNO$V_DEB_CONT] = yes; runoff_command[RNO$V_DEB_FILES] = yes; runoff_command[RNO$V_DEB_INDEX] = yes; END; IF .scan_result[formsize] NEQ -1 ! If /FORMSIZE was specified, THEN ! runoff_command[RNO$G_FORM_SIZE] = ! put the "form size" count in the command block. .scan_result[formsize]; ! IF .scan_result[overprint] EQL 1 ! If /OVERPRINT was specified, THEN ! runoff_command[RNO$V_OVERPRINT] = yes; ! indicate so in the command block. IF .scan_result[pause] EQL 1 ! If /PAUSE was specified, THEN ! runoff_command[RNO$V_PAUSE] = yes; ! indicate so in the command block. IF .scan_result[right] NEQ -1 ! If /RIGHT was specified, THEN ! runoff_command[RNO$G_RIGHT] = ! put the "right" count in the command block. .scan_result[right]; ! IF .scan_result[sequence] EQL 1 ! If /SEQUENCE was specified, THEN ! runoff_command[RNO$V_SEQUENCE] = yes; ! indicate so in the command block. IF .scan_result[simulate] NEQ -1 ! If /SIMULATE was specified, THEN ! runoff_command[RNO$V_SIMULATE] = yes; ! indicate so in the command block. IF .scan_result[underline] EQL 0 ! If /UNDERLINE:0 or /NOUNDERLINE was specified, THEN ! runoff_command[RNO$V_UNDERLINE] = no; ! turn off the default underlining indicator. IF .scan_result[underline] GTR 0 ! If an underlining character was specified or defaulted, THEN ! BEGIN ! runoff_command[RNO$V_UNDERLINE] = yes; ! indicate underlining was requested runoff_command[RNO$V_UND_CHAR] = yes; ! and that an underline character was specified. runoff_command[RNO$C_UNDERLINE] = ! .scan_result[underline]; ! Save the underline character. END; ! ! 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. X10$EXIT_FLAG = yes; ! Next call on X10$RETURN exits to the monitor. IF NOT .status ! If RUNOFF returns a failure code, THEN ! terminate RUNOFF processing rather than RETURN .status; ! trying another command. END; ! End of processing an actual (non-null) command. END ! End of processing any command line. END; ROUTINE CLEAR_RESULTS : NOVALUE = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine zeros all RUNOFF command line information in ! preparation for processing a new command line. ! ! FORMAL PARAMETERS: ! ! None ! ! IMPLICIT INPUTS: ! ! None ! ! IMPLICIT OUTPUTS: ! ! None ! ! ROUTINE VALUE: ! ! None ! ! SIDE EFFECTS: ! ! None ! !-- BEGIN BIND rno_cmd = runoff_command : VECTOR; ! Redefine command block for easy initialization. MAP input_scan_spec : VECTOR, ! Change the structure of the several list_scan_spec : VECTOR, ! file-spec areas from block to vector to make toc_scan_spec : VECTOR, ! zeroing of these areas easier. index_scan_spec : VECTOR; ! ! Initialize the RUNOFF command block. ! INCR index FROM 0 TO RNO$K_CMD_LNG DO ! Zero the RUNOFF command information block rno_cmd[.index] = 0; ! one element at a time. runoff_command[RNO$V_UNDERLINE] = yes; ! Assume default underlining. ! ! Clear all of the RUNOFF command information. ! INCR index FROM 0 TO max_switch_code DO ! Loop through the command information vector, scan_result[.index] = -1; ! setting the entire vector to -1. ! ! Zero the input, listing, contents and index file specification areas. ! INCR index FROM 0 TO SCAN$K_FXLEN-1 DO BEGIN input_scan_spec[.index] = 0; list_scan_spec[.index] = 0; toc_scan_spec[.index] = 0; index_scan_spec[.index] = 0; END; ! ! Return to SCAN. ! RETURN ! Return to the caller (SCAN). END; ROUTINE ALL_INPUT : NOVALUE = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine returns the address and length of an input ! file specification information area for use by SCAN. ! ! FORMAL PARAMETERS: ! ! None ! ! IMPLICIT INPUTS: ! ! None ! ! IMPLICIT OUTPUTS: ! ! None ! ! ROUTINE VALUE: ! ! Register 1 = Address of file specification area ! Register 2 = Length of file specification area ! ! SIDE EFFECTS: ! ! None ! !-- BEGIN GLOBAL REGISTER ! Define return value registers: address = 1, ! address of input file-spec area length = 2; ! length of input file-spec area address = input_scan_spec; ! Put the file-spec area address and length = SCAN$K_FXLEN; ! length into SCAN-specific registers. RETURN ! Return to the caller (SCAN). END; ROUTINE ALL_OUTPUT : NOVALUE = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine returns the address and length of an output ! file specification information area for use by SCAN. ! ! FORMAL PARAMETERS: ! ! None ! ! IMPLICIT INPUTS: ! ! None ! ! IMPLICIT OUTPUTS: ! ! None ! ! ROUTINE VALUE: ! ! Register 1 = Address of file specification area ! Register 2 = Length of file specification area ! ! SIDE EFFECTS: ! ! None ! !-- BEGIN GLOBAL REGISTER ! Define return value registers: address = 1, ! address of output file-spec area length = 2; ! length of output file-spec area address = list_scan_spec; ! Put the file-spec area address and length = SCAN$K_FXLEN; ! length into SCAN-specific registers. RETURN ! Return to the caller (SCAN). END; ROUTINE STORE_VALUE( dummy ) : $SCAN_G12 NOVALUE = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine saves ASCII string switch values. ! ! FORMAL PARAMETERS: ! ! None ! ! IMPLICIT INPUTS: ! ! Register 1 (switch_value) - value of current switch ! Register 2 (switch_table) - switch code value ! ! IMPLICIT OUTPUTS: ! ! None ! ! ROUTINE VALUE: ! ! None ! ! SIDE EFFECTS: ! ! NOTE: This routine does a normal return to indicate that the switch ! value has been processed; it does a "skip return" back to SCAN ! to continue normal switch value processing. ! !-- BEGIN LINKAGE KLUDGE = PUSHJ : LINKAGE_REGS(15,13,1) ! ***** TEMPORARY ***** PRESERVE(2,6,7,8,9,10,11,12,14) NOPRESERVE(1,3,4,5); ROUTINE CH$$PTR( BASE, INDEX ) : KLUDGE = ! ***** TEMPORARY ***** CH$PTR( .BASE, .INDEX ); EXTERNAL REGISTER switch_table; ! Global register 2 LOCAL store_code; ! Code portion of switch_table LOCAL character, ! Single ASCII character scan_pointer, ! Pointer to SCAN internal string buffer local_pointer; ! Pointer to local string save area ! ! Select appropriate switch value processing. ! store_code = .switch_table AND %O'777777'; ! Extract the code portion of switch_table value. SELECTONE .store_code OF ! Use the "store code" to select special processing. SET ! ! /CONTENTS special processing. ! [toc_scan_spec] : BEGIN runoff_command[RNO$V_CONTENTS] = yes; ! Indicate /CONTENTS was specified SKIP_RETURN; ! and do a skip-return to complete switch processing. END; ! ! /INDEX special processing. ! [index_scan_spec] : BEGIN runoff_command[RNO$V_INDEX] = yes; ! Indicate /INDEX was specified SKIP_RETURN; ! and do a skip-return to complete switch processing. END; ! ! /PAGES value string processing. ! [pages] : BEGIN BIND pages = runoff_command[RNO$T_PAGES] : ! Redefine the pages string descriptor. $STR_DESCRIPTOR(); scan_pointer = CH$PTR( SCAN$NMUL ); ! Point to SCAN's internal string buffer local_pointer = CH$$PTR( pages_string, ! and into the local string save area. .pages[STR$H_LENGTH] ); IF .pages[STR$H_LENGTH] EQL 0 ! If this is the first /PAGES value, THEN ! $STR_DESC_INIT( DESCRIPTOR = pages, ! setup the string descriptor in the command block. STRING = ( 0, .local_pointer ) ) ELSE BEGIN ! Otherwise, add a comma to the current string IF .pages[STR$H_LENGTH] LSS ! if there is enough room in the string area. max_page_str THEN BEGIN CH$WCHAR_A( %C',', local_pointer ); pages[STR$H_LENGTH] = .pages[STR$H_LENGTH] + 1; END; END; INCR count FROM 1 TO max_quoted_str DO ! Save the entire string. BEGIN IF .pages[STR$H_LENGTH] GEQ ! If the /PAGES string area is full, max_page_str ! THEN ! EXITLOOP; ! ignore the remaining value characters. character = ! Pickup a single character. CH$RCHAR_A( scan_pointer ); IF .character EQL 0 ! If the end of the string has been reached, THEN ! EXITLOOP; ! exit the string saving loop. CH$WCHAR_A( .character,local_pointer ); ! Otherwise, save the character, pages[STR$H_LENGTH] = ! increment the string length, .pages[STR$H_LENGTH] + 1; ! END; ! and loop. END; ! ! /VARIANT value string processing. ! [variant] : BEGIN BIND variant = ! Redefine the variant string descriptor. runoff_command[RNO$T_VARIANT]: $STR_DESCRIPTOR(); scan_pointer = CH$PTR( SCAN$NMUL ); ! Point to SCAN's internal string buffer local_pointer = CH$$PTR( variant_string, ! and into the local string save area. .variant[STR$H_LENGTH] ); IF .variant[STR$H_LENGTH] EQL 0 ! If this is the first /VARIANT value, THEN ! $STR_DESC_INIT( DESCRIPTOR = variant, ! setup the string descriptor in the command block. STRING = ( 0, .local_pointer ) ) ELSE BEGIN ! Otherwise, add a comma to the current string IF .variant[STR$H_LENGTH] LSS ! if there is enough room in the string area. max_page_str THEN BEGIN CH$WCHAR_A( %C',', local_pointer ); variant[STR$H_LENGTH] = .variant[STR$H_LENGTH] + 1; END; END; INCR count FROM 1 TO max_quoted_str DO ! Save the entire string. BEGIN IF .variant[STR$H_LENGTH] GEQ ! If the /VARIANT string area is full, max_page_str ! THEN ! EXITLOOP; ! ignore the remaining value characters. character = ! Pickup a single character. CH$RCHAR_A( scan_pointer ); IF .character EQL 0 ! If the end of the string has been reached, THEN ! EXITLOOP; ! exit the string saving loop. CH$WCHAR_A( .character,local_pointer ); ! Otherwise, save the character, variant[STR$H_LENGTH] = ! increment the string length, .variant[STR$H_LENGTH] + 1; ! END; ! and loop. END; TES; ! ! Return to the caller. ! RETURN ! Return to the caller indicating no value to be set. END; ROUTINE CHANGE_PARSE : $SCAN_G78 NOVALUE = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine parses a /CHANGE switch value. ! ! FORMAL PARAMETERS: ! ! None ! ! IMPLICIT INPUTS: ! ! Register 8 (character) - current delimiter character (not used) ! ! IMPLICIT OUTPUTS: ! ! None ! ! ROUTINE VALUE: ! ! Register 7 (switch_value) - change bar character (switch value) ! Register 8 (character) - current delimiter character ! ! SIDE EFFECTS: ! ! None ! !-- BEGIN EXTERNAL REGISTER switch_value, ! Switch value character; ! Current character GLOBAL REGISTER keyword_info = 1; ! Error message routine global indicator ! ! Parse the switch value which must be a quoted character or an octal number. ! GET_CHAR_VALUE(); ! Get a character value in the switch_value register. IF .switch_value LSS 0 ! If the value was in error, THEN ! BEGIN ! keyword_info = -1; ! indicate an unknown keyword $SCAN_ERROR( UKK ); ! and jump to a SCAN error return. END; ! ! Return the character value to SCAN. ! RETURN ! Return the character value to SCAN. END; ROUTINE DEBUG_PARSE( dummy ) : $SCAN_G78 NOVALUE = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine parses a /DEBUG switch value. ! ! FORMAL PARAMETERS: ! ! None ! ! IMPLICIT INPUTS: ! ! Register 8 (character) - current delimiter character (not used) ! ! IMPLICIT OUTPUTS: ! ! None ! ! ROUTINE VALUE: ! ! None ! ! SIDE EFFECTS: ! ! NOTE: This routine performs a "skip return" back to SCAN to ! indicate that no value should be stored. ! !-- BEGIN EXTERNAL REGISTER switch_value, ! Switch value character; ! Current character GLOBAL REGISTER keyword_info = 1; ! Keyword lookup global register BUILTIN UUO; ! UUO function needed for PUSHJ kludge (see below). ! ! Parse a keyword value. ! SCAN$SIXSW(); ! Get a 6-bit keyword in the switch_value register. keyword_info = ! Setup the length and address of the keyword SCAN$IOWD( debug_l, debug_t ); ! table in a global parameter register. IF NOT UUO( 1, %O'260', %O'17', SCAN$NAME ) ! Call the SCAN keyword lookup routine ! (i.e, PUSHJ SP,SCAN$NAME). THEN ! If the keyword lookup fails, $SCAN_ERROR( UKK ); ! jump to a SCAN error return. CASE .keyword_info - debug_t ! Use the keyword table index to FROM 0 TO max_deb_key OF ! select appropriate keyword processing. SET [ deb_all_key ] : ! ALL: BEGIN ! runoff_command[RNO$V_DEB_COND] = yes; ! Turn on all debug indicators. runoff_command[RNO$V_DEB_CONT] = yes; runoff_command[RNO$V_DEB_FILES] = yes; runoff_command[RNO$V_DEB_INDEX] = yes; END; [ deb_cond_key ] : ! CONDITIONALS runoff_command[RNO$V_DEB_COND] = yes; [ deb_cont_key ] : ! CONTENTS runoff_command[RNO$V_DEB_CONT] = yes; [ deb_files_key ] : ! FILES runoff_command[RNO$V_DEB_FILES] = yes; [ deb_index_key ] : ! INDEX runoff_command[RNO$V_DEB_INDEX] = yes; TES; ! ! Perform a "skip return" back to SCAN to indicate value processing is complete. ! SKIP_RETURN ! "Skip return" back to SCAN. END; ROUTINE UNDER_PARSE( dummy ) : $SCAN_G78 NOVALUE = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine parses a /UNDERLINE switch value. ! ! FORMAL PARAMETERS: ! ! None ! ! IMPLICIT INPUTS: ! ! Register 8 (character) - current delimiter character (not used) ! ! IMPLICIT OUTPUTS: ! ! None ! ! ROUTINE VALUE: ! ! None ! ! SIDE EFFECTS: ! ! NOTE: This routine performs a "skip return" back to SCAN to ! indicate that no value should be stored. ! !-- BEGIN EXTERNAL REGISTER switch_value, ! Switch value character; ! Current character GLOBAL REGISTER keyword_info = 1; ! Keyword lookup global register BUILTIN UUO; ! UUO function needed for PUSHJ kludge (see below). ! ! Assume that underlining is being requested. ! runoff_command[RNO$V_UNDERLINE] = yes; ! Assume that underlining is requested. ! ! Parse a possible quoted character or octal value. ! GET_CHAR_VALUE(); ! Get a character value in the switch_value register. IF .switch_value GEQ 0 ! If a valid character was found, THEN ! BEGIN ! runoff_command[RNO$V_UND_CHAR] = yes; ! indicate that a keyword character was specified, runoff_command[RNO$C_UNDERLINE] = ! save the UNDERLINE character, .switch_value; ! SKIP_RETURN; ! and perform a "skip return" to SCAN. END; ! ! Parse a keyword value. ! SCAN$SIXSC(); ! Get a 6-bit keyword in the switch_value register. keyword_info = ! Setup the length and address of the keyword SCAN$IOWD( underline_l, underline_t ); ! table in a global parameter register. IF NOT UUO( 1, %O'260', %O'17', SCAN$NAME ) ! Call the SCAN keyword lookup routine ! (i.e, PUSHJ SP,SCAN$NAME). THEN ! If the keyword lookup fails, $SCAN_ERROR( UKK ); ! jump to a SCAN error return. CASE .keyword_info - underline_t ! Use the keyword table index to FROM 0 TO max_und_key OF ! select appropriate keyword processing. SET [ und_nonsp_key ] : ! NONSPACING: runoff_command[RNO$V_UND_NONSP] = yes; ! Turn on the non-spacing character indicator. [ und_separ_key ] : ! SEPARATE: runoff_command[RNO$V_UND_SEPAR] = yes; ! Turn on the separate line indicator. TES; ! ! Perform a "skip return" back to SCAN to indicate value processing is complete. ! SKIP_RETURN ! "Skip return" back to SCAN. END; ROUTINE GET_CHAR_VALUE : $SCAN_G78 NOVALUE = !++ ! ! FUNCTIONAL DESCRIPTION: ! ! This routine parses a switch value which must be a quoted ! character or an octal number. ! ! FORMAL PARAMETERS: ! ! None ! ! IMPLICIT INPUTS: ! ! Register 8 (character) - current delimiter character (not used) ! ! IMPLICIT OUTPUTS: ! ! None ! ! ROUTINE VALUE: ! ! Register 7 (switch_value) - change bar character (switch value) ! or ! an error code (-1) ! Register 8 (character) - current delimiter character ! ! SIDE EFFECTS: ! ! None ! !-- BEGIN EXTERNAL REGISTER switch_value, ! Switch value character; ! Current character ! ! Process a quoted character. ! SCAN$TIAUC(); ! Get the 1st value character in character. IF .character EQL %C'"' ! If it is a quotation mark, THEN ! BEGIN ! SCAN$TISQT(); ! pickup the next character switch_value = .character; ! and put it in the return register. IF .SCAN$QUOTE EQL 0 ! If there is any problem, THEN ! $SCAN_ERROR( SVR ); ! jump to a SCAN error return. SCAN$LASWD = SCAN$TFCHR; ! Otherwise, indicate single character format SCAN$TIAUC(); ! and process the trailing quotation mark. RETURN; ! Return the character value to the caller. END; ! ! Process an octal value. ! IF .character LSS %C'A' ! If the value is not a keyword, THEN ! parse an octal value. BEGIN SCAN$OCTNC(); ! Pass the first octal character in character ! and get back the value in switch_value. IF .switch_value LSS 0 ! If a negative value was specified, THEN ! $SCAN_ERROR( SVNG ); ! jump to a SCAN error return. IF .switch_value GTR %O'177' ! If the value is too large to be an ASCII character, THEN ! $SCAN_ERROR( SVTL ); ! jump to a SCAN error return. RETURN; ! Return the character value to the caller. END; ! ! Return an error code to the caller. ! switch_value = -1; ! Indicate that a keyword was specified RETURN ! and return to the caller. END; END ELUDOM