Google
 

Trailing-Edge - PDP-10 Archives - BB-X117B-SB_1986 - 10,7/nml/ncprsp.bli
There are 2 other files named ncprsp.bli in the archive. Click here to see a list.
! UPD ID= 321, SNARK:<6.1.NML>NCPRSP.BLI.18,   7-May-85 21:50:28 by GLINDELL
!  Update tabular displays now that we can use the full screen width
!
! UPD ID= 304, SNARK:<6.1.NML>NCPRSP.BLI.17,  29-Apr-85 18:37:04 by GLINDELL
!  Another CRLF before 'request' in FMT_HEADER to make left justification
!  pretty.  Add 'request formatting' argument to call to NCP$SEND_RESPONSE.
!
! UPD ID= 300, SNARK:<6.1.NML>NCPRSP.BLI.16,  27-Apr-85 18:03:10 by GLINDELL
!  Do not tabular display for 'LOOP NODES'
!
! UPD ID= 298, SNARK:<6.1.NML>NCPRSP.BLI.15,  24-Apr-85 13:00:43 by GLINDELL
!  Remove typeout of node address if node number is zero.  There are a
!  few bugs (notably in X25 code) that will cause a zero node number.
!  Don't make it worse by typing out something.
!
! UPD ID= 296, SNARK:<6.1.NML>NCPRSP.BLI.13,  18-Mar-85 16:04:10 by MCCOLLUM
! Don't display LOOP NODE = FOO anymore in a SHOW command. It is possible
! for a node address to be zero and not be a loop node. There is not enough
! information available in FMT_ENTITY_HEADER to determine if the node is a
! LOOP node.
!
! UPD ID= 279, SNARK:<6.1.NML>NCPRSP.BLI.12,   6-Mar-85 23:11:35 by GLINDELL
!  Add hooks for network management event parameter 1 that has special C-1
!
! UPD ID= 263, SNARK:<6.1.NML>NCPRSP.BLI.11,   1-Mar-85 10:00:51 by GLINDELL
!  Fix up many places where area # wasn't defaulted.
!
! UPD ID= 236, SNARK:<6.1.NML>NCPRSP.BLI.10,  20-Jan-85 16:47:53 by GLINDELL
!  1. Default area number in FMT_NODE_ID_FIELD if it is missing
!  2. Make the name for node number = 0 equal to 'Area_router'
!  3. Output node name for CMN's and events
!
! UPD ID= 227, SNARK:<6.1.NML>NCPRSP.BLI.9,  15-Jan-85 15:10:29 by HALPIN
! Replace Tabular Format macros that were removed in UPD 133.  Circuit info
! is now returned with one NICE Message per adjacency, fixing the problem
! of the ADJACENT NODE Parameter overwriting itself.  This also
! fixes the problems of IPCF buffers overflowing.
!
! UPD ID= 224, SNARK:<6.1.NML>NCPRSP.BLI.8,  18-Dec-84 16:22:25 by HALPIN
! Get ride of all code that suppresses the display of Area 1 in a Node
! Address, i.e. Node 1.25 used to print out as just 25.
!
! UPD ID= 139, SNARK:<6.1.NML>NCPRSP.BLI.7,  26-Oct-84 15:52:44 by GUNN
! Ident 58.
!
! Fix $RSP_TEXT to properly handle failure return of call to NMU$TEXT when
! the output buffer overflows. It wasn't deducting the text length that
! was written into the output stream when the buffer overflowed, thus
! writing past the end of the buffer on the next call.
!
! Also, required a fix in NMU$TEXT to return the correct output count
! on output overflow.
!
! UPD ID= 133, SNARK:<6.1.NML>NCPRSP.BLI.6,  19-Oct-84 15:48:51 by HALPIN
! Hack up Tabular formats so Adjacent Nodes and their Qualified Parameters
! all print out on SHOW KNOWN CIRCUIT displays.
!
! UPD ID= 61, SNARK:<6.1.NML>NCPRSP.BLI.5,  26-Jun-84 15:10:13 by GLINDELL
! Fix bug in FMT_SINGLE_CODED_FIELD when the parameter was not known
!
! UPD ID= 60, SNARK:<6.1.NML>NCPRSP.BLI.4,  26-Jun-84 13:16:32 by GLINDELL
! Circumvent BLISS bug in FMT_EVENT_LIST_FIELD
! Fix some comments in NCP$EVENT_FMT_DATA
!
! UPD ID= 24, SNARK:<6.1.NML>NCPRSP.BLI.3,  24-May-84 14:13:21 by GLINDELL
! Fix $RSP_TEXT macro to handle error returns from $NMU$TEXT
!
! PH4:<GLINDELL>NCPRSP.BLI.7 16-Feb-84 12:56:57, Edit by GLINDELL
!
! Ident 53.
!  Add NCP$EVENT_FMT_DATA to format event parameters
!
! PH4:<GLINDELL>NCPRSP.BLI.22  1-Feb-84 13:08:07, Edit by GLINDELL
!
! Ident 52
!  Display event lists
!
! DSKC:NCPRSP.BLI[10,5665,SOURCE,TOPS10] 16-Oct-83 18:48:27, Edit by GROSSMAN
!
! Fix reporting of command name in GET_COMMAND_NAME for change type commands.
! Ie; add %b to binary fields in a CASE statement.
!
!<MCINTEE>NCPRSP.BLI.2, 15-Sep-83 14:30:20, Edit by MCINTEE
!
! Ident 51.
!  LINE display bug fix
!
!<MCINTEE.WORK>NCPRSP.BLI.2,  5-Aug-83 12:42:57, Edit by MCINTEE
!
! Ident 50.
!  ENTITY_AREA bug fix
!
!<MCINTEE.WORK>NCPRSP.BLI.2, 22-Jul-83 15:13:46, Edit by MCINTEE
!
! Ident 49.
!  Subentity type now in entity type.
!  Change GET_ENTITY_ID fill in subentity type as needed.
!
!<MCINTEE.WORK>NCPRSP.BLI.2, 6-Jul-83 12:09:06, Edit by MCINTEE
!
! Ident 48.
!  Tabular format bug
!
!<MCINTEE.WORK>NCPRSP.BLI.5, 14-Jun-83 11:27:58, Edit by MCINTEE
! 
! Ident 47.
!  New style entity type constant names
! 
!<MCINTEE>NCPRSP.BLI.2, 17-Jun-83 07:57:05, Edit by MCINTEE
!
! Ident 46.
!  Fix NCP$DEQUEUE_RESPONSE for tabular format. Initial line
!  (Request #37; Show ... completed) was omitted. 
!
!<MCINTEE.WORK>NCPRSP.BLI.7,  9-Jun-83 08:57:18, Edit by MCINTEE
!
! Ident 45.
!  Fix NCP$DEQUEUE_RESPONSE for tabular format, checking the first 
!  entity id in the first message of a node response for executor.
!
! PH4:<MCINTEE>NCPRSP.BLI.2,  1-Jun-83 10:11:05, Edit by MCINTEE
!
! Ident 44.
!  Fix FMT_TABULAR_DATA.
!
! PH4:<PECKHAM>NCPRSP.BLI.77 31-May-83 10:10:37, Edit by PECKHAM
!
! Ident 43.
!   Add tabular format definition macro, expansion macros, and data base
!   expansion.  Routines FMT_TABULAR_* are added to do tabular response
!   processing.
!
! PH4:<PECKHAM>NCPRSP.BLI.17 17-May-83 13:04:09, Edit by PECKHAM
!
! Ident 42.
!   Add support for the following Phase IV changes:
!      AREA entity, KNOWN/ACTIVE AREAS.
!      node addresses with area numbers.
!
!   Change entity case ranges to use ENTITY_LO to ENTITY_HI.
!
!   Replace use of NML$PARAMETER_LOOKUP by NML$INFORMATION, so as to keep
!   the construction of parameter tables hidden.
!   Begin code for tabular reponses.
!
!   Change FMT_PARAMETER to use the format index from NML$DATA_TYPE
!   to do special data formatting (like node-ids and versions).
!
! <BRANDT.DEVELOPMENT>NCPRSP.BLI.1 29-Sep-82 14:21:45, Edit by BRANDT
!
! Ident 41.
!   In NCP$DEQUEUE_RESPONSE do not release any memory for CANCELLED
!   requests without first checking to see if something has been
!   allocated.
!
! <BRANDT.DEVELOPMENT>NCPRSP.BLI.1 27-Sep-82 14:12:54, Edit by BRANDT
!
! Ident 40.
!   A minor cosmetic fix to FMT_ENTITY_HEADER to make the formatting
!   of the identification for loop nodes consistent with other nodes.
!
! <BRANDT.DEVELOPMENT>NCPRSP.BLI.1 14-Sep-82 17:21:32, Edit by BRANDT
!
! Ident 39.
!   Fix code for printing out test data bytes in error responses to
!   LOOP_ messages.
!
! <BRANDT.DEVELOPMENT>NCPRSP.BLI.1 1-Sep-82 14:12:23, Edit by BRANDT
!
! Ident 38.
!   In routine FMT_UNCODED_FIELD, fix the code that formats long fixed
!   binary fields.  The response message will have low order bytes
!   first.
!
! <BRANDT.DEVELOPMENT>NCPRSP.BLI.1 5-Aug-82 11:21:32, Edit by BRANDT
!
! Ident 37.
!   1) Change NCP$DEQUEUE_RESPONSE so that commands like SET KNOWN ...
!      and ZERO KNOWN ... produce output consistent with NM spec.
!   2) Rework edit 35.
!
! <BRANDT.DEVELOPMENT>NCPRSP.BLI.1 28-Jul-82 17:12:23, Edit by BRANDT
!
! Ident 36.
!   1) In NCP$DEQUEUE_RESPONSE set RESPONSE_DATA flag in request block
!      when response message indicates an error.  That way, we don't get
!      "No Information" with an error message.
!
! <BRANDT.DEVELOPMENT>NCPRSP.BLI.1 28-Jun-82 10:12:23, Edit by BRANDT
!
! Ident 35.
!   1) In NCP$DEQUEUE_RESPONSE do not call FMT_ENTITY_HEADER to
!      format the entity from the response message if we are processing
!      an error.  Call GET_ENTITY_ID directly and thus avoid such
!      constructs as LOOP NODE = FOO, when FOO is an unrecognized
!      node name.
!
! <BRANDT.DEVELOPMENT>NCPRSP.BLI.2 7-Jun-82 11:21:45, Edit by BRANDT
!
! Ident 34.
!   1) In NCP$DEQUEUE_RESPONSE release memory allocated for node_id
!      in the request block.  Before this edit, this memory was
!      released in NML$NICE_EXECUTE.  Doing so allowed the memory to
!      be reallocated while still being referenced as a node_id.
!      Yep!  You guessed it.  Strange, occasional errors.
!
! <BRANDT.DEVELOPMENT>NCPRSP.BLI.2 13-May-82 9:12:45, Edit by BRANDT
!
! Ident 33.
!   1) In NCP$DEQUEUE_RESPONSE make changes required to handle partial
!      response messages (code of 3)
!   2) In FMT_RESPONSE_DATA, terminate text message with a blank and
!      null rather than a CR and null.
!
! <BRANDT.DEVELOPMENT>NCPRSP.BLI.2 10-May-82 10:21:54, Edit by BRANDT
!
! Ident 32.
!   1) Remove calls to FMT_ERROR_INFO and FMT_ENTITY_HEADER for response
!      messages with a code of 2 or -128.
!
! <BRANDT.DEVELOPMENT>NCPRSP.BLI.2 29-Apr-82 15:12:11, Edit by BRANDT
!
! Ident 31.
!   1) Change FMT_ERROR_DETAIL so it will not return FALSE if
!      .ERR_DETAIL value is 0, since this could be a valid value for
!      some error codes.  (URC for example!)
!   2) Change FMT_ERROR_INFO so it will call FMT_ERROR_DETAIL only if
!      the response code indicates an error.
!   3) Make FMT_ERROR_INFO a "no value" function.
!   4) Add a parameter to GET_COMMAND_NAME so that function can also
!      return a pointer to the type of information requested on read
!      commands.
!   5) Fix up FMT_HEADER routine and calls to it so that messages
!      conform (more or less) to the Network Management Spec.
!   6) Change GET_ENTITY_NAME so that the string returned will include
!      the specific class of entity, if applicable. (i.e., KNOWN,
!      ACTIVE, LOOP, or EXECUTOR)
!   7) Change FMT_RESPONSE_DATA to fix the "No Information" problem
!      by keeping a flag in the request block that indicates if any
!      data is returned for the request.  This fix makes SHOW KNOWN ...
!      work.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPRSP.BLI.4  9-Apr-82 15:07:05, Edit by VOBA
!
! Ident 30.
! Fix FMT_UNCODED_FIELD to display binary image field with specific format.
!
! <VOBA.NML.DEVELOPMENT>NCPRSP.BLI.4  8-Apr-82 14:06:33, Edit by VOBA
!
! Ident 29.
! Fix bug in parsing binary image field data in routine FMT_UNCODED_FIELD.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPRSP.BLI.32 25-Mar-82 15:54:40, Edit by VOBA
!
! Ident 28.
! Change code to format response message display for qualified MODULE
! parameters.
! Fix code to display cluster of returned parameters in the same entry.
! Fix code to use field definitions of NICE options.
!
! NET:<PECKHAM.DEVELOPMENT>NCPRSP.BLI.6 26-Feb-82 14:06:39, Edit by PECKHAM
!
! Ident 27.
! Move error detail text to NMARCH.
! Surround response texts by $NML$TEXT and convert to lower case;
! $NML$TEXT in NMARCH can be made to raise case if necessary.
! Produce error if NMU$MEMORY_GET fails in NCP$DEQUEUE_RESPONSE.
!
! <VOBA.NML.DEVELOPMENT>NCPRSP.BLI.3 24-Feb-82 08:12:30, Edit by VOBA
!
! Ident 26.
! Fix 'No Information' by
!   1) Get NICE return code in NCP$DEQUEUE_RESPONSE
!   2) Passing return code to FMT_RESPONSE_DATA
!   3) Displaying 'No Information' if command was READ_ and the return code
!      is not 2 (meaning separated data responses are coming)
!
! NET:<PECKHAM.DEVELOPMENT>NCPRSP.BLI.7 22-Feb-82 10:46:14, Edit by PECKHAM
!
! Ident 25.
! Change GET_ERR_DETAIL into FMT_ERR_DETAIL,
! Make it insert the error detail response text,
! and interpret the error detail information.
! Change GET_ENTITY_NAME to return null pointer with unidentified entity.
! Set up $RSP_TEXT to parenthesize statement and use this great macro!
!
! NET:<PECKHAM.DEVELOPMENT>NCPRSP.BLI.2 19-Feb-82 20:52:00, Edit by PECKHAM
!
! Ident 24.
! Fix LOGGING entity display in FMT_ENTITY_HEADER.
! Fix LOGGING entity verification in GET_ENTITY_ID.
! Re-install 'No Information' by
!   1) Getting NICE command code in NCP$DEQUEUE_RESPONSE
!   2) Passing command code to FMT_RESPONSE_DATA
!   3) Displaying 'No Information' if command was READ_
!
! NET:<VOBA.NML.DEVELOPMENT>NCPRSP.BLI.3 19-Feb-82 11:54:28, Edit by VOBA
!
! Ident 23.
! Removed unused debugging local variables.
!
! NET:<VOBA.NML.DEVELOPMENT>NCPRSP.BLI.13 16-Feb-82 15:05:45, Edit by VOBA
!
! Ident 22.
! Replacing old debugging code (check %O'135') with %debug macro.
!
! NET:<PECKHAM.DEVELOPMENT>NCPRSP.BLI.2  8-Feb-82 08:10:07, Edit by PECKHAM
!
! Ident 21.
! The 'No Information' response was not well thought out -
! the SET command has no information in the response!
! Remove the 'No Information'.
!
! NET:<PECKHAM.DEVELOPMENT>NCPRSP.BLI.2  8-Feb-82 07:40:43, Edit by PECKHAM
!
! Ident 20.
! Fix bug introduced in #19.
!
! NET:<PECKHAM.DEVELOPMENT>NCPRSP.BLI.3  7-Feb-82 16:32:30, Edit by PECKHAM
!
! Ident 19.
! Add 'No Information' response when no response data given
! in FMT_RESPONSE_DATA.
! Add MAX_VALUE to INTERPRET_COUNTER to identify counter overflow.
!
! NET:<BRANDT.DEVELOPMENT>NCPRSP.BLI.3 18-Jan-82 16:22:11, Edit by BRANDT
!
! Ident 18.
!   Change routine GET_ERR_DETAIL so that response messages with an
!   error detail field equal to 65535 (applicable but not available)
!   will not have any text printed.
!
! NET:<BRANDT.DEVELOPMENT>NCPRSP.BLI.2 15-Jan-82 15:12:11, Edit by BRANDT
!
! Ident 17.
!   Change NCP$DEQUEUE_RESPONSE to handle error messages that might
!   be part of a sequence of response messages.
!
! NET:<BRANDT.DEVELOPMENT>NCPRSP.BLI.2 11-Jan-82 15:57:11, Edit by BRANDT
!
! Ident 16.
! Add support to allow multiple NICE response text to be returned in a
! single IPCF packet. Handle overflow of text to more than one IPCF
! packet.
! Update copyright date to 1982.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPRSP.BLI.6  9-Oct-81 15:38:11, Edit by WEBBER
!
! Ident 15.
! Change blanks to tabs in counter formatting.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPRSP.BLI.6  7-Oct-81 9:54:26, Edit by WEBBER
!
! Ident 14.
! Fix counter formatting code.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPRSP.BLI.5  1-Oct-81 15:17:54, Edit by WEBBER
!
! Ident 13.
! Add code to get counter/bitmap text string.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NCPRSP.BLI.38  6-Aug-81 14:34:34, Edit by JENNESS
!
! Ident 12.
! Add return codes -100 to -103.  (DECnet-10/20 specific).
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPRSP.BLI.5 12-May-81 13:29:37, Edit by GUNN
!
! Ident 11.
! Fix typo from last edit. Change %upval to %bpval.
! Bump RESP_PTR after saving for use in long binary value.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPRSP.BLI.2 12-May-81 10:09:02, Edit by GUNN
!
! Ident 10.
! Fix FMT_UNCODED_FIELD to handle long binary values correctly.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPRSP.BLI.9 16-Apr-81 11:25:37, Edit by GUNN
!
! Add code to convert coded NODE parameters to text.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPRSP.BLI.7 15-Apr-81 17:16:58, Edit by GUNN
!
! Add first level of code necessary to format names of parameters on output.
!
! NET:<DECNET20-V3P1.NML>NCPRSP.BLI.4 29-Mar-81 13:59:28, Edit by GUNN
!
! Change names of all routines beginning FORMAT_ to FMT_ making them
! unique to six characters, in order that they may be found when
! using DDT.
!
! NET:<DECNET20-V3P1.NML>NCPRSP.BLI.3 25-Mar-81 17:38:34, Edit by GUNN
!
! Increase size of text buffer used for response text.
! Change TEXT_BFR_SZ to TEXT_BUFFER_SIZE and add TEXT_BUFFER_LENGTH
! and TEXT_BUFFER_ALLOCATION for use where appropriate.
!
! NET:<DECNET20-V3P1.NML>NCPRSP.BLI.2 24-Mar-81 12:44:04, Edit by GUNN
!
! Release text buffer used in processing response.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NCPRSP.BLI.32 11-Feb-81 10:51:24, Edit by GUNN
!
! Send debugging output of response message contents back to operator in
! separate message. Large repsonse messages cause text buffer to overflow.
! Move call to text routine to end text with null byte into routine
! FMT_RESPONSE_DATA.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NCPRSP.BLI.30  9-Feb-81 14:57:24, Edit by GUNN
!
! Make output of uncoded parameter fields be dependent on DATA TYPE encoding.
! Output headers on multiple response sequence only first time.
! Special case test for length of node name in response message to account
! for bit 7 being set to indicate "EXECUTOR" node.
! Change output of node address to decimal.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NCPRSP.BLI.22  5-Feb-81 17:38:43, Edit by GUNN
!
! Handle multiple coded fields in response parameters properly. Loop was
! executed once too many times.
!
! NET:<DECNET20-V3P1.BASELEVEL-2.SOURCES>NCPRSP.BLI.21  4-Feb-81 19:43:29, Edit by GUNN
!
! Make release of memory resources associated with request storage be
! dependent on RB_STATE being set to RB$DONE.
!
! Update copyright date to 1981.
!
%title 'NCPRSP -- Process NICE Response Message'
module NCPRSP	(
		ident = 'X04.58'
		) =
begin

!                  COPYRIGHT (c) 1980,1981,1982,1983,1984 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:	DECnet-10/20 V3.0 Network Control Program (NCP)
!
! ABSTRACT:
!
!	Performs processing of NICE response messages. Called by NML request
!	queue manager at request completion time. Transforms the NICE response
!	message to a text message and calls NCP$SEND_RESPONSE to transmit the
!	message text to the operator.
!
! ENVIRONMENT:	TOPS-10/20 User mode under NML
!
! AUTHOR: Dale C. Gunn , CREATION DATE:  8-Oct-80
!
! MODIFIED BY:
!
!	, : VERSION
! 01	-
!--
!
! INCLUDE FILES:
!

library 'NCPLIB';                       ! All required definitions
require 'NCPEXT';                       ! NCP External Names

!
! TABLE OF CONTENTS
!

forward routine
	NCP$DEQUEUE_RESPONSE: novalue,
        GET_COMMAND_NAME,
        GET_ENTITY_NAME,
        FMT_HEADER : novalue,
        FMT_ERROR_INFO : novalue,
        FMT_ERR_DETAIL,
        FMT_ENTITY_HEADER,
        GET_ERR_MESSAGE,
        GET_ENTITY_ID,
        GET_LINK_ERR_TEXT,
        GET_FILE_ERR_TEXT,
        FMT_RESPONSE_DATA,
        NCP$EVENT_FMT_DATA : novalue,
        FMT_COUNTER,
        INTERPRET_COUNTER,
        FMT_PARAMETER : novalue,
        FMT_SINGLE_CODED_FIELD : novalue,
        FMT_UNCODED_FIELD : novalue,
        FMT_NODE_ID_FIELD : novalue,
        FMT_EVENT_LIST_FIELD : novalue,
        FMT_TABULAR_HEADER,
        FMT_TABULAR_DATA : novalue,
        FMT_TABULAR_ENTITY : novalue;


%sbttl 'Tabular Format Definitions'


macro $NCP$TABULAR_FORMATS =

    (ENTITY_NODE,
       (SUMMARY_,(
'      Node       State       Active  Delay  Circuit       Next node',
'                             links'),                                   %(
 ---------------- 0 --------- 600 --  601 -- 822 ------ ----- 830 ------
 12.3456 (ABCDEF) Unreachable 123     123    KDP-0-0.0  12.3456 (ABCDEF) )%
              (    ,  1, 16, Node),
              (   0, 18, 12),
              ( 600, 31,  3, Right),
              ( 601, 39,  3, Right),
              ( 822, 45, 10),
              ( 830, 56, 16, Node)),

       (STATUS_,(
'      Node       State      Active Delay Type           Cost Hops Circuit',
'                            Links'),                                      %(
 ---------------- 0 ----------- 600---601-810-------------820--821 822 ---
 12.3456 (ABCDEF) Unreachable   123   123 Nonrouting III 1234  123 KDP-0-0.0 )%
              (    ,  1, 16, Node),
              (   0, 18, 11),
              ( 600, 30,  3, Right),
              ( 601, 37,  3, Right),
              ( 810, 42, 14),
              ( 820, 57,  4, Right),
              ( 821, 63,  3, Right),
              ( 822, 67,  10))),

    (ENTITY_CIRCUIT,

       (SUMMARY_, (
'Circuit     State                  Loopback    Adjacent',
'                                     Name        Node'),    %(
 ----------- 0-1 ------------------ -- 400 ------- 800 ------
 KDP-0-0.127 Service-Autotriggering (ABCDEF) 12.3456 (ABCDEF) )%
              (    ,  1, 11),
              (   0, 13,  7),
              (   1,   , 14, Float),
              ( 400, 37,  6),
              ( 800, 45, 16, Node)),
               (STATUS_, (
'Circuit     State                  Loopback    Adjacent      Block',
'                                     Name        Node         Size'), %(
 ----------- 0-1 ------------------ -- 400-------- 800 ----- -- 810
 KDP-0-0.127 Service-Autotriggering (ABCDEF) 12.3456 (ABCDEF) 65535    )%
              (    ,  1, 11),
              (   0, 13,  7),
              (   1,   , 14, Float),
              ( 400, 37,  6),
              ( 800, 45, 16, Node),
              ( 810, 62,  5, Right))),

    (ENTITY_LINE,

       ((SUMMARY_,STATUS_),
'Line     State',                %(
 -------- 0-1 ------------------
 PAM-0-15 Service-Autotriggering )%
              (    ,  1,  8),
              (   0, 10,  7),
              (   1,   , 14, Float))),


%(
    (ENTITY_LOGGING,

       (SUMMARY_,
'    Sink Node       Source               Events                   State Name',
              (    ,  1, 16, Node),
              (   0, 68,  3),
              ( 200, 21, 16),
              ( 201, 42, 26))),
)%

    (ENTITY_AREA, 

       (SUMMARY_,
'Area State       Circuit     Next node to area', %(
  --  0 --------- 822 -------- ----- 830 ------
  37  Unreachable KDP-0-0.127  12.3456 (ABCDEF)   )%
              (    ,  2,  2),
              (   0,  6, 11),
              ( 822, 18, 12),
              ( 830, 31, 16, Node))) %;

%sbttl 'Macro Definitions'

macro
     NEXTB_RESP =
         NEXTB (.RESP_LEN,RESP_POS) %;

macro
     NEXTF_RESP =
         NEXTF (.RESP_LEN,RESP_POS,.RESP_PTR) %;

macro
     NEXTW_RESP =
         NEXTW (.RESP_LEN,RESP_POS) %;

macro
     NEXTN_RESP (N) =
         NEXTN (.RESP_LEN,RESP_POS,N) %;

!
! Macro to perform text output. Updates pointer to next available byte of
! text and current text length available.
!

macro
     $RSP_TEXT (FMT) =
         (local I;
          I = $NMU$TEXT (TEXT_PTR,
                         (TEXT_BUFFER_LENGTH-.TEXT_LENGTH),
                         FMT
                         %if %length gtr 1
                         %then ,%remaining
                         %fi);
          if .I geq 0
          then TEXT_LENGTH = .TEXT_LENGTH + .I
          else
              begin
              TEXT_LENGTH = .TEXT_LENGTH +  ABS(.I); ! Return count is negative
              TASK_INFO('INTERNAL ERROR IN NMLT20: Overflow in display buffer in NCPRSP');
              end) %;

%sbttl 'Equated Symbols'

%module_name ('NCPRSP');                ! Declare tracing facility

literal
    TEXT_BUFFER_LENGTH = 2534,          ! Maximum characters in IPCF response
    TEXT_BUFFER_SIZE = ch$allocation (TEXT_BUFFER_LENGTH), ! In words
    TEXT_BUFFER_ALLOCATION = TEXT_BUFFER_SIZE * %upval;

$show (all);

$field HDR_FIELDS =
    set
    HDR_ENTITY = [$integer],            ! Entity type for table
    HDR_INFORMATION_TYPE = [$short_integer], ! Information type selected
    HDR_HEADER = [$address],            ! Pointer to header text pattern
    HDR_PARAMETER_LIST = [$address],    ! Address of parameter insertion list
    HDR_WIDTH = [$short_integer]        ! Width of information line
    tes;

literal
    HDR_SIZE = $field_set_size;

macro
    HDR_BLOCK =
        block field (HDR_FIELDS) %;

!
! Interpretive text is placed in a field of specified length, and
! is justified or centered.  Column numbers start with 0 (for ease
! with ch$plus).
!

$field PRM_FIELDS =
    set
    PRM_NUMBER = [$integer],            ! Parameter number
    PRM_COLUMN = [$byte],               ! Start text at this column
    PRM_LENGTH = [$byte],               ! Text field length
    PRM_FORMAT = [$byte]                ! Field formatting
    tes;

$literal
    PRM_FMT_RIGHT = $distinct,          ! Right justify
    PRM_FMT_CENTER = $distinct,         ! Center the text
    PRM_FMT_LEFT = 0,                   ! Left justify
    PRM_FMT_NODE = $distinct,           ! Center node format
    PRM_FMT_FLOAT = $distinct,          ! Float after last text
    PRM_FMT_LO = min (PRM_FMT_RIGHT, PRM_FMT_CENTER, PRM_FMT_LEFT,
                      PRM_FMT_NODE, PRM_FMT_FLOAT),
    PRM_FMT_HI = max (PRM_FMT_RIGHT, PRM_FMT_CENTER, PRM_FMT_LEFT,
                      PRM_FMT_NODE, PRM_FMT_FLOAT);

literal
    PRM_SIZE = $field_set_size;

macro
    PRM_BLOCK =
        block field (PRM_FIELDS) %;

$show (none);

macro
    $NCP$HDR_COUNT [] =
        (0 + $NCP$HDR_CNT ($NCP$HDR_LIST (%remaining))) %,
    $NCP$HDR_PRESET [] =
        $NCP$HDR_SET ($NCP$HDR_LIST (%remaining)) %,
    $NCP$HDR_LIST [FMT] = $NCP$HDR_SET_ENTITY (%remove (FMT)) %,
    $NCP$HDR_CNT [ENT, INF, WIDE, HDR_ADR, PRM_ADR] = 1 %,
    $NCP$HDR_SET [ENT, INF, WIDE, HDR_ADR, PRM_ADR] =
        [%count, HDR_ENTITY] = ENT,
        [%count, HDR_INFORMATION_TYPE] = INF,
        [%count, HDR_WIDTH] = WIDE,
        [%count, HDR_HEADER] = uplit (HDR_ADR),
        [%count, HDR_PARAMETER_LIST] = PRM_ADR %,
    $NCP$HDR_SET_ENTITY (ENT) [INF_LST] =
        $NCP$HDR_SET_INFO_LIST (ENT, %remove (INF_LST)) %,
    $NCP$HDR_SET_INFO_LIST (ENT, INF) =
        $NCP$HDR_SET_INFO (ENT, $NCP$HDR_DESC (%remaining), %remove (INF)) %,
    $NCP$HDR_SET_INFO (ENT, HDR_ADR, WIDE, PRM_ADR) [INF] =
        ENT, INF, WIDE, HDR_ADR, PRM_ADR %,
    $NCP$HDR_DESC (TEXT) =
        $NML$TEXT (%string ($NCP$HDR_TEXT (%remove (TEXT)), '%N')),
        max ($NCP$HDR_WIDTH_LIST (%remaining)),
        plit ($NCP$PRM_ENTRY_LIST (%remaining)) %,
    $NCP$HDR_TEXT [TEXT] = TEXT, '%/' %,
    $NCP$HDR_WIDTH_LIST [PRM_LST] = $NCP$HDR_WIDTH (%remove (PRM_LST)) %,
    $NCP$HDR_WIDTH (NUM, COL, WID, JST) = (COL - 1 + WID) %,
    $NCP$PRM_ENTRY_LIST [PRM_LST] = $NCP$PRM_ENTRY (%remove (PRM_LST)) %,
    $NCP$PRM_ENTRY (NUM, COL, WID, JST) =
        %if not %null(NUM) %then (NUM) %else -1 %fi,
        %if not %null(COL) %then (COL - 1)^%fieldexpand(PRM_COLUMN,1) %else 0 %fi
         or (WID)^%fieldexpand(PRM_LENGTH,1)
        %if %identical (JST,Left) or %null (JST) %then
         or PRM_FMT_LEFT^%fieldexpand(PRM_FORMAT,1) %fi
        %if %identical (JST,Center) %then
         or PRM_FMT_CENTER^%fieldexpand(PRM_FORMAT,1) %fi
        %if %identical (JST,Right) %then
         or PRM_FMT_RIGHT^%fieldexpand(PRM_FORMAT,1) %fi
        %if %identical (JST,Float) %then
         or PRM_FMT_FLOAT^%fieldexpand(PRM_FORMAT,1) %fi
        %if %identical (JST,Node) %then
         or PRM_FMT_NODE^%fieldexpand(PRM_FORMAT,1) %fi %;

!
! OWN STORAGE:
!

own
   HDR_TABLE : blockvector [$NCP$HDR_COUNT ($NCP$TABULAR_FORMATS), HDR_SIZE]
               field (HDR_FIELDS)
               preset ($NCP$HDR_PRESET ($NCP$TABULAR_FORMATS));

own
   RESP_LEN,                            ! Length of response message
   RESP_POS,                            ! Current position in response message
   NICE_PTR,                            ! Character pointer to NICE message
   RESP_PTR,                            ! Character pointer to NICE response
   HDR_ADDR: ref HDR_BLOCK initial (0), ! Header of active tabular display
   HDR_CONTROL: initial (-1),           ! <0 - do not include header
                                        ! =0 - include header next response
                                        !      if necessary
                                        ! =1 - include header next response
                                        ! >1 - include header on Nth response
   SEND_PTR,                            ! Pointer to text to be displayed
   TEXT_PTR,                            ! Character pointer text response msg
   TEXT_LENGTH;                         ! Length of text message in characters

!
! EXTERNAL REFERENCES:
!

external
    %debug_data_base;

external routine
         PUTBUF,                        ! Debugging output in NCPCEX
         NCP$GET_ERR_TEXT,
         NCP$TEST_RESPONSE,
         NCP$SEND_RESPONSE,
         NCP$SEND_TO_OPERATOR,
         NCP$LOG_TO_OPERATOR,
  	 NML$GET_SUBENTITY_ID,		! Get module subentity type 
         NML$PARAMETER_TEXT,            ! Return text pointer to parameter name
         NML$INFORMATION,               ! Check information type applicability
         NML$DATA_TYPE,                 ! Get parameter data type/format
	 NCP$COUNTER_TEXT,		! Return text pointer to counter name
	 NCP$BIT_TEXT,			! Return text ptr to bitmap bit name
         NML$CODED_TEXT,                ! Return text pointer to coded text
         NMU$NETWORK_LOCAL,             ! Return local node ID
         NML$CONVERT_ENTITY_ID;        ! Convert entity ID
%global_routine ('NCP$DEQUEUE_RESPONSE', REQ) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Called by the NML request manager as a completion routine
!       to process the response to a NICE request. Formats a message
!       text to be returned to the issuer of the NCP command which
!       caused the request to be generated. The text is formatted
!       in accordance with the NICE request and response messages
!       pointed to by the request block.
!
! FORMAL PARAMETERS
!
!
!	REQ  - Address of the NML request block.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    own
	 LAST_RTN_CODE: block[1] initial(0); ! From previous resp msg

    local
         CMD_CODE,                      ! Command code
         CMD_PTR,                       ! Pointer to command name
         ENT_PTR,                       ! Pointer to entity type name
         EID_PTR,                       ! Pointer to entity ID
         EID_LEN,                       ! Entity ID len
         NOD_ADR,                       ! Temp variable
         SELECTOR,                      ! Information type
         MSG_TYPE,                      ! Type of message to send to operator
         STS_PTR,                       ! Pointer to status string
         RTN_COD: $SIGNED_BYTE_VALUE,   ! NICE return code
         ENTITY_TYPE : FULL_ENTITY,     ! Full entity type 
         ERR_DETAIL,                    ! Value of error detail field
         REQ_DATA,                      ! Our special data
         TEXT_ADDR,                     ! Address of text buffer
	 T1,				! Temporary
	 T2,				! Temporary
	 T3,				! Temporary
         TEMP;                          ! Local work variable

    map
       REQ: ref REQUEST_BLOCK,          ! Make fields addressable
       REQ_DATA: ref XCTR_BLOCK;        ! Make fields addressable

!
! **Caution**  If a request was queued, but hasn't been started yet, some of
! it's data base (response data and such) may not be set up.  The only way to
! detect this is to see if the pointer to the data in question is zero or not.
! It is up to the person who sets up these pointers to ensure their integrity!
! The previous monologue has a lot to do with the following piece of code.
!
    if .REQ[RB_STATE] eql RB$CANCELLED  ! Request was cancelled
    then begin                          ! Release all associated storage
	if ((.REQ[RB_DATA] neq 0) and
	    (.REQ[RB_DATA_ALLOCATION] neq 0))
        then NMU$MEMORY_RELEASE (.REQ[RB_DATA],.REQ[RB_DATA_ALLOCATION]);
	if ((.REQ[RB_RESPONSE] neq 0) and
	    (.REQ[RB_RESPONSE_ALLOCATION] neq 0))
        then NMU$MEMORY_RELEASE (.REQ[RB_RESPONSE],.REQ[RB_RESPONSE_ALLOCATION]);
	if ((.REQ[RB_NICE] neq 0) and
	    (.REQ[RB_NICE_ALLOCATION] neq 0))
        then NMU$MEMORY_RELEASE (.REQ[RB_NICE],.REQ[RB_NICE_ALLOCATION]);
	if .REQ[RB_NICE_ENTITY_ADR] neq 0 ! Release node id buffer
	then NMU$MEMORY_RELEASE (.REQ[RB_NICE_ENTITY_ADR],
				 NODE_ID_BUFFER_ALLOCATION);
        NMU$MEMORY_RELEASE (.REQ,REQUEST_BLOCK_ALLOCATION);
        return;
        end;

    TEMP = .REQ[RB_TYPE];               ! Get request type RT$REMOTE/RT$LOCAL 
    NICE_PTR = ch$ptr(.REQ[RB_NICE],,8); ! Get pointer to NICE request
    TEMP = .REQ[RB_NICE_LENGTH];        ! And its length in bytes
    EID_PTR = ch$plus(.NICE_PTR,2);     ! Pointer to Entity ID
    REQ_DATA = .REQ[RB_DATA];           ! Address of NCP specific data
    RESP_LEN = .REQ[RB_RESPONSE_LENGTH]; ! Length of response message
    RESP_PTR = ch$ptr (.REQ[RB_RESPONSE],,8); ! Get pointer to NICE response 

    TEXT_ADDR = NMU$MEMORY_GET (TEXT_BUFFER_ALLOCATION); ! Allocate buffer

    if .TEXT_ADDR eql 0
    then $INTERNAL_ERROR$ ('Unable to get response text buffer');

    TEXT_PTR = SEND_PTR = ch$ptr(.TEXT_ADDR); ! Initialize text pointer
    TEXT_LENGTH = 0;                    ! Length of text initially zero

!
! Analyze and convert NICE request to text
!

    CMD_CODE = ch$rchar (.NICE_PTR);
    CMD_PTR = GET_COMMAND_NAME (ENTITY_TYPE, SELECTOR, NICE_PTR);

    if .CMD_CODE neq READ_		! Only get expanded
    then				!  entity names
	EID_PTR = 0;			!  for SHOW command

    ENT_PTR = GET_ENTITY_NAME (.ENTITY_TYPE, .EID_PTR);

    if .ENT_PTR eqla 0
    then ENT_PTR = CH$ASCIZ ($NML$TEXT ('*Unknown Entity*'));

!
! Process NICE response message
!

    %debug (NCP_NICE_VALIDATION,        ! Debugging code
           (begin                       ! Used to print the content of the
            builtin LSH;                ! NICE message in ASCII text for
            local PAGE, PTR, TMP;       ! displaying in log file.

            PAGE = NMU$PAGE_GET ();
            PTR = TMP = ch$ptr (LSH (.PAGE,9));
            $NMU$TEXT (TMP, TEXT_BUFFER_LENGTH,
                       '%/[NICE Response Message]%/%N');
            PUTBUF (TMP, 0,             ! Format the NICE message
                    .REQ[RB_RESPONSE],
                    .REQ[RB_RESPONSE_LENGTH]);
            NCP$SEND_RESPONSE (0, .PTR, .REQ_DATA[OPR_ID], 1);
            NMU$PAGE_RELEASE (.PAGE);
            end));

    RESP_POS = 0;                       ! Initially at beginning of response
    MSG_TYPE = -1;			! Initially no message to operator
    STS_PTR = CH$ASCIZ ($NML$TEXT ('Completed')); ! Status

    if NEXTB_RESP
    then RTN_COD = GETB (RESP_PTR)      ! Get NICE return code
    else $INTERNAL_ERROR$ ('Zero length response received');


    selectone .RTN_COD[VALUE] of        ! Process according to return code
        set
        [1]:                            ! Success
            begin
            if .REQ[RB_STATE] eql RB$DONE
            then MSG_TYPE = 0        ! Final and only operator message
            else MSG_TYPE = 2;       ! Part of multiple segment message

	    if ((.MSG_TYPE eql 0) and
		(.CMD_CODE neq CHANGE_) and
		(.CMD_CODE neq ZERO_))
	    then
		FMT_TABULAR_HEADER (.ENTITY_TYPE, .SELECTOR);

	    if ((.MSG_TYPE eql 0) or
		(.CMD_CODE eql CHANGE_) or
		(.CMD_CODE eql ZERO_))
	    then
                 FMT_HEADER (.REQ[RB_NUMBER],
                             .CMD_PTR,
                             .ENT_PTR,
                             .SELECTOR,
                             .STS_PTR);

            FMT_ERROR_INFO (.ENTITY_TYPE, ! Format any error info
                            .RTN_COD[VALUE],
			    ERR_DETAIL);

	    SEND_PTR = .TEXT_PTR;

	    if .LAST_RTN_CODE neq 3	  ! If not more of a partial rsp
            then			  ! Format entity
	        FMT_ENTITY_HEADER (ENTITY_TYPE,.RTN_COD[VALUE],.CMD_CODE)
	    else
		GET_ENTITY_ID (T1, T2, T3, ENTITY_TYPE); ! Skip it

            !
            ! Display data in sentence or tabular format depending
            ! on whether there is a table format available.  In the
            ! case of NODE responses, the first response may be the
            ! EXECUTOR, which must be displayed in sentence format.
            !

            if .HDR_CONTROL geq 0
            then 
		 begin			! Tabular format
		 label IS_EXECUTOR;
                 if .HDR_CONTROL gtr 0
                 then 
IS_EXECUTOR:  	      begin	      
                      if (HDR_CONTROL = .HDR_CONTROL - 1) gtr 0
                      then begin  ! Node entity. Could be executor.
		      	   T1 = ch$ptr (.REQ[RB_RESPONSE],3,8);	! Get to response text.
			   T1 = ch$plus (.T1,  ch$rchar_a (T1) + 2);	! Step past text and node address.
			   T2 = ch$rchar (.T1);	! Get count byte of entity id
		           if (.T2<7,1> eql 1)  ! Check the 'is executor' bit
                           ! Check if it is 'LOOP NODES' - no tabular then
                           or begin
                                local LEN : $SIGNED_BYTE_VALUE,
                                      PTR;

                                PTR = .EID_PTR;
                                LEN = GETB (PTR);
                                .LEN [VALUE] eql LOOPED_
                              end
			   then begin	! It is executor.
		                FMT_RESPONSE_DATA (.ENTITY_TYPE, .CMD_CODE, .REQ);
			        leave IS_EXECUTOR;
			        end;
			   end;
                      TEXT_PTR = .SEND_PTR; ! Cancel entity header and
                      $RSP_TEXT ('%2/%N');  ! Insert a break before header.
		      HDR_CONTROL = 0;		! Never insert a break again.
                      FMT_TABULAR_DATA (.REQ);
                      SEND_PTR = ch$ptr (.TEXT_ADDR); ! Include header
                      end	! End of IS_EXECUTOR
                 else begin
                      TEXT_PTR = .SEND_PTR; ! Cancel entity header.
                      FMT_TABULAR_DATA (.REQ);
                      end;
                 end
            else FMT_RESPONSE_DATA (.ENTITY_TYPE, .CMD_CODE, .REQ);
            end;

        [2]:                            ! Request accepted, more response 
            begin
                MSG_TYPE = 1;               ! First part of message
                FMT_TABULAR_HEADER (.ENTITY_TYPE, .SELECTOR);   ! See if this will be in tabular format
                FMT_HEADER (.REQ[RB_NUMBER], .CMD_PTR, .ENT_PTR, .SELECTOR, .STS_PTR); ! Initial line.
            end;

        [3]:                            ! Success, partial reply
            begin
            HDR_CONTROL = -1;           ! Tabular response can't handle -cancel
            MSG_TYPE = 2;               ! Part of multiple segment message
            FMT_ERROR_INFO (.ENTITY_TYPE, ! Format any error info
                            .RTN_COD[VALUE],
			    ERR_DETAIL);

	    if .LAST_RTN_CODE neq 3	  ! If not more of a partial rsp
            then			  ! Format entity
	        FMT_ENTITY_HEADER (ENTITY_TYPE,.RTN_COD[VALUE],.CMD_CODE)
	    else
		GET_ENTITY_ID (T1, T2, T3, ENTITY_TYPE); ! Skip it

            FMT_RESPONSE_DATA (.ENTITY_TYPE, ! Format parameters
                               .CMD_CODE,
                               .REQ);
            end;

        [-29 to -1,
         -103 to -100]:                 ! Error
            begin
            if ((.REQ[RB_STATE] eql RB$DONE) or
	        (.CMD_CODE eql CHANGE_) or
		(.CMD_CODE eql ZERO_))
            then begin
                 MSG_TYPE = 0;          ! Final and only operator message
                 STS_PTR = CH$ASCIZ ($NML$TEXT ('Failed')); ! Status
                 FMT_HEADER (.REQ[RB_NUMBER],
                             .CMD_PTR,
                             .ENT_PTR,
                             .SELECTOR,
                             .STS_PTR);
                 end
            else MSG_TYPE = 2;          ! Part of multiple part message

            TEMP = NCP$GET_ERR_TEXT (.RTN_COD[VALUE]); ! Get error text pointer
            $RSP_TEXT (', %#A%N', ch$rchar (ch$plus(.TEMP,-1)), .TEMP);

            FMT_ERROR_INFO (.ENTITY_TYPE, ! Format any error detail and text
                            .RTN_COD[VALUE],
			    ERR_DETAIL);

	    FMT_ENTITY_HEADER (ENTITY_TYPE,.RTN_COD[VALUE],.CMD_CODE);

	    REQ[RB_RESPONSE_DATA] = 1;          ! Set flag non-zero

            if .REQ[RB_NICE_FUNCTION] eql LOOP_ ! TEST request response
            then begin                  	!  has special format
                 local TEST_DATA;

                 if NEXTW_RESP          ! TEST DATA field exist?
                 then begin
                      TEST_DATA = GETW (RESP_PTR); ! Get special code
                      if (.RTN_COD[VALUE] eql NICE$_IPV) ! Failed for invalid parm value
                      and (.ERR_DETAIL eql N$LLTH) ! Length parameter
                      then begin        ! Max test data length exceeded
                           $RSP_TEXT ($NML$TEXT ('%/ Maximum test data length = %D, exceeded%/'),
                                      .TEST_DATA);
                           end
                      else begin        ! Unlooped count
                           $RSP_TEXT ($NML$TEXT ('%/ Unlooped count = %D%/'),
                                      .TEST_DATA);
                           end;
                      end;
                  end
            else $RSP_TEXT ('%/');
            end;

        [-128]:                         ! Final multiple response
            begin
            MSG_TYPE = 3;               ! Last of multiple operator messages
            if ((.CMD_CODE eql READ_) and   ! Function is READ
                (.REQ[RB_RESPONSE_DATA] eql 0)) ! No data ever supplied
            then $RSP_TEXT ($NML$TEXT ('%/%/  No Information%/'));
            end;

        [otherwise]:                    ! Invalid return code
            begin
            MSG_TYPE = 0;               ! Final and only operator message
            STS_PTR = CH$ASCIZ ($NML$TEXT ('Failed')); ! Status
            FMT_HEADER (.REQ[RB_NUMBER],
                        .CMD_PTR,
                        .ENT_PTR,
                        0,	        ! No information type
                        .STS_PTR);
            $RSP_TEXT ($NML$TEXT (',%/Invalid NICE return code = (%D)%/'),
                       .RTN_COD);
            end;
        tes;

    LAST_RTN_CODE = .RTN_COD[VALUE];	! Remember return code

    !
    ! Send the response text back to operator
    !

    if .MSG_TYPE geq 0
    then begin
         if (.HDR_CONTROL leq 0) and
            not NCP$TEST_RESPONSE (.MSG_TYPE, .SEND_PTR, .REQ_DATA[OPR_ID])
         then SEND_PTR = ch$ptr (.TEXT_ADDR); ! Include header
         NCP$SEND_RESPONSE (.MSG_TYPE, .SEND_PTR, .REQ_DATA[OPR_ID], 1);
         end;

    !
    ! Release all storage associated with the request
    ! Release all memory resources when done
    !

    NMU$MEMORY_RELEASE (.TEXT_ADDR, TEXT_BUFFER_ALLOCATION);

    if .REQ[RB_STATE] eql RB$DONE
    then begin
         HDR_CONTROL = -1;
         NMU$MEMORY_RELEASE (.REQ[RB_DATA], .REQ[RB_DATA_ALLOCATION]);
         NMU$MEMORY_RELEASE (.REQ[RB_RESPONSE], .REQ[RB_RESPONSE_ALLOCATION]);
         NMU$MEMORY_RELEASE (.REQ[RB_NICE], .REQ[RB_NICE_ALLOCATION]);
	 if .REQ[RB_NICE_ENTITY_ADR] neq 0 ! Release node id buffer
	 then NMU$MEMORY_RELEASE (.REQ[RB_NICE_ENTITY_ADR],
				  NODE_ID_BUFFER_ALLOCATION);
         NMU$MEMORY_RELEASE (.REQ, REQUEST_BLOCK_ALLOCATION);
         end;

    end;				! End of NCP$DEQUEUE_RESPONSE
%routine ('GET_COMMAND_NAME', ENTITY_TYPE_ADDR, INF_TYP_ADDR, NICE_PTR_ADDR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Determines the NCP command name string based on the NICE 
!       request message.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE_ADDR        The address of variable in which will be
!                               returned the entity type number found in
!                               the NICE message.
!
!	INF_TYP_ADDR            The address of variable in which will be
!                               returned the information type in a "read"
!                               NICE message.  For other NICE messages,
!				this variable will be set to -1.
!
!	NICE_PTR_ADDR           The address of a pointer to the beginning
!                               of a NICE request message.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	A character sequence pointer to the NCP command name string.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map
	ENTITY_TYPE_ADDR : ref FULL_ENTITY;

    local
	 TEMP;                          ! Local work variable

    .INF_TYP_ADDR = -1;			! Set null, initially

    TEMP = GETB (.NICE_PTR_ADDR);       ! Get the NICE function code

    case .TEMP from LOAD_ to SYSTEM_SPECIFIC_ of
        set
        [LOAD_]:                        ! Request down-line load
            begin
            local OPTION: block [1] field (LOAD_OPTIONS);

            TEMP = CH$ASCIZ ($NML$TEXT ('Load'));
            OPTION = GETB (.NICE_PTR_ADDR); ! Get option byte
            .ENTITY_TYPE_ADDR = .OPTION[LO_ENTITY_TYPE]; ! Get entity type
            end;

        [DUMP_]:                        ! Request up-line dump
            begin
            local OPTION: block [1] field (DUMP_OPTIONS);

            TEMP = CH$ASCIZ ($NML$TEXT ('Dump'));
            OPTION = GETB (.NICE_PTR_ADDR); ! Get option byte
            .ENTITY_TYPE_ADDR = .OPTION[DO_ENTITY_TYPE]; ! Get entity type
            end;

        [TRIGGER_]:                     ! Trigger bootstrap
            begin
            local OPTION: block [1] field (BOOT_OPTIONS);

            TEMP = CH$ASCIZ ($NML$TEXT ('Trigger'));
            OPTION = GETB (.NICE_PTR_ADDR); ! Get option byte
            .ENTITY_TYPE_ADDR = .OPTION[BO_ENTITY_TYPE]; ! Get entity type
            end;

        [LOOP_]:                        ! Test
            begin
            local OPTION: block [1] field (TEST_OPTIONS);

            TEMP = CH$ASCIZ ($NML$TEXT ('Loop'));
            OPTION = GETB (.NICE_PTR_ADDR); ! Get option byte
            .ENTITY_TYPE_ADDR = .OPTION[TO_ENTITY_TYPE]; ! Get entity type
            end;

        [SET_]:                         ! Change parameter
            begin
            local OPTION: block [1] field (CHANGE_OPTIONS);

            OPTION = GETB (.NICE_PTR_ADDR); ! Get option byte
            selectone .OPTION[CO_FUNCTION_DATA] of
                set
                [%b'00']: TEMP = CH$ASCIZ ($NML$TEXT ('Set'));
                [%b'01']: TEMP = CH$ASCIZ ($NML$TEXT ('Clear'));
                [%b'10']: TEMP = CH$ASCIZ ($NML$TEXT ('Define'));
                [%b'11']: TEMP = CH$ASCIZ ($NML$TEXT ('Purge'));
                tes;

            .ENTITY_TYPE_ADDR = .OPTION[CO_ENTITY_TYPE]; ! Get entity type
            end;

        [SHOW_]:                        ! Read information
            begin
            local OPTION: block [1] field (READ_OPTIONS);

            OPTION = GETB (.NICE_PTR_ADDR); ! Get option byte
            selectone .OPTION[RO_PERMANENT] of
                set
                [0]: TEMP = CH$ASCIZ ($NML$TEXT ('Show'));
                [1]: TEMP = CH$ASCIZ ($NML$TEXT ('List'));
                tes;

            .INF_TYP_ADDR = .OPTION[RO_INFO_TYPE];
            .ENTITY_TYPE_ADDR = .OPTION[RO_ENTITY_TYPE]; ! Get entity type
            end;

        [ZERO_]:                        ! Zero counters
            begin
            local OPTION: block [1] field (ZERO_OPTIONS);

            TEMP = CH$ASCIZ ($NML$TEXT ('Zero'));
            OPTION = GETB (.NICE_PTR_ADDR); ! Get option byte
            .ENTITY_TYPE_ADDR = .OPTION[ZO_ENTITY_TYPE]; ! Get entity type
            end;

        [SYSTEM_SPECIFIC_]:             ! System-specific function
            begin
            %( N.B. - Unknown for now until we know what system specific
                      functions we will be supporting. )%
            TEMP = CH$ASCIZ ($NML$TEXT ('*System Specific*'));
            .ENTITY_TYPE_ADDR = -1;     ! Set entity type invalid
            end;

        [inrange,
         outrange]:                     ! * Invalid *
            begin
            TEMP = CH$ASCIZ ($NML$TEXT ('*Unknown*'));
            .ENTITY_TYPE_ADDR = -1;     ! Set entity type invalid
            end;
        tes;
	if ..ENTITY_TYPE_ADDR eql ENTITY_MODULE then
	begin				     ! Get submodule type from request.
	   local
	     SEID_STRING : CH$SEQUENCE [80], ! String storage for subentity id.
	     SEID_LEN : $SIGNED_BYTE_VALUE,  ! Length of subentity id.
	     SEID_PTR,			     ! Pointer to string.
	     SEID : FULL_ENTITY;

	     SEID_LEN = ch$rchar (..NICE_PTR_ADDR);
	     if .SEID_LEN gtr 0 then
	     begin
 	          SEID_PTR = ch$ptr (SEID_STRING,,7);	! Convert to 7 bit bytes.
 	          ch$move (.SEID_LEN, ch$plus(..NICE_PTR_ADDR,1), .SEID_PTR);
	          
	          SEID = ..ENTITY_TYPE_ADDR;	     ! Get subentity type
	          SEID[ENTITY_SUB] = NML$GET_SUBENTITY_ID (.SEID_LEN, .SEID_PTR);
	          .ENTITY_TYPE_ADDR = .SEID;
	          end;
	     end;

    return .TEMP;                       ! Returning pointer to command string
    end;				! End of GET_COMMAND_NAME
%routine ('GET_ENTITY_NAME', ENTITY_TYPE, EID_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Converts the entity type number to a pointer to a string which
!       represents the name of the entity.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - A value which represents the full entity type.
!
!	EID_PTR - Pointer to the entity ID in NICE message
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	A character sequence pointer to the entity name string
!       or null pointer if unidentified.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    map 
	ENTITY_TYPE : FULL_ENTITY;

    local
	EID_LEN: $SIGNED_BYTE_VALUE,
	PTR;				! Temporary loc for ptr

    PTR = .EID_PTR;
    EID_LEN = (if .PTR neq 0
               then GETB(PTR)
               else 0);

    return case .ENTITY_TYPE[ENTITY_MAIN] from ENTITY_LO to ENTITY_HI of
        set
       [ENTITY_AREA]:
	    selectone .EID_LEN[VALUE] of
		set
		[KNOWN_]: CH$ASCIZ ($NML$TEXT ('Known Areas'));
		[ACTIVE_]: CH$ASCIZ ($NML$TEXT ('Active Areas'));
		[SIGNIFICANT_]: CH$ASCIZ ($NML$TEXT ('Significant Areas'));
		[otherwise]: CH$ASCIZ ($NML$TEXT ('Area'));
		tes;
       [ENTITY_NODE]:
	    selectone .EID_LEN[VALUE] of
		set
		[0]:
		    if .PTR neq 0
	            then
			begin
                        local
                            NODE_ID;    ! Node address
			NODE_ID = GETW (PTR);
			if .NODE_ID eql 0
			then CH$ASCIZ ($NML$TEXT ('Executor Node'))
			else CH$ASCIZ ($NML$TEXT ('Node'))
			end
		    else
			CH$ASCIZ ($NML$TEXT ('Node'));

		[KNOWN_]: CH$ASCIZ ($NML$TEXT ('Known Nodes'));

		[ACTIVE_]: CH$ASCIZ ($NML$TEXT ('Active Nodes'));

		[LOOPED_]: CH$ASCIZ ($NML$TEXT ('Loop Nodes'));

		[ADJACENT_]: CH$ASCIZ ($NML$TEXT ('Adjacent Nodes'));

		[SIGNIFICANT_]: CH$ASCIZ ($NML$TEXT ('Significant Nodes'));

		[otherwise]: CH$ASCIZ ($NML$TEXT ('Node'));

		tes;

       [ENTITY_LINE]:
	    selectone .EID_LEN[VALUE] of
		set
		[KNOWN_]: CH$ASCIZ ($NML$TEXT ('Known Lines'));
		[ACTIVE_]: CH$ASCIZ ($NML$TEXT ('Active Lines'));
		[SIGNIFICANT_]: CH$ASCIZ ($NML$TEXT ('Significant Lines'));
		[otherwise]: CH$ASCIZ ($NML$TEXT ('Line'));
		tes;

       [ENTITY_LOGGING]:
	    selectone .EID_LEN[VALUE] of
		set
		[KNOWN_]: CH$ASCIZ ($NML$TEXT ('Known Logging'));
		[ACTIVE_]: CH$ASCIZ ($NML$TEXT ('Active Logging'));
		[SIGNIFICANT_]: CH$ASCIZ ($NML$TEXT ('Significant Logging'));
		[otherwise]: CH$ASCIZ ($NML$TEXT ('Logging'));
		tes;

       [ENTITY_CIRCUIT]:
	    selectone .EID_LEN[VALUE] of
		set
		[KNOWN_]: CH$ASCIZ ($NML$TEXT ('Known Circuits'));
		[ACTIVE_]: CH$ASCIZ ($NML$TEXT ('Active Circuits'));
		[SIGNIFICANT_]: CH$ASCIZ ($NML$TEXT ('Significant Circuits'));
		[otherwise]: CH$ASCIZ ($NML$TEXT ('Circuit'));
		tes;

       [ENTITY_MODULE]:
	    selectone .EID_LEN[VALUE] of
		set
		[KNOWN_]: CH$ASCIZ ($NML$TEXT ('Known Modules'));
		[ACTIVE_]: CH$ASCIZ ($NML$TEXT ('Active Modules'));
		[SIGNIFICANT_]: CH$ASCIZ ($NML$TEXT ('Significant Modules'));
		[otherwise]: CH$ASCIZ ($NML$TEXT ('Module'));
		tes;

        [inrange,
         outrange]: 0;
        tes;

    end;				! End of GET_ENTITY_NAME
%routine ('FMT_HEADER', REQ_NO, CMD_PTR, ENT_PTR, INF_TYP, STS_PTR) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Formats the initial header line of command response output.
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin
    local INF_PTR;

    case .INF_TYP from INFORMATION_LO to INFORMATION_HI of
        set
        [SUMMARY_]: INF_PTR = CH$ASCIZ ($NML$TEXT('Summary '));
        [STATUS_]: INF_PTR = CH$ASCIZ ($NML$TEXT('Status '));
        [CHARACTERISTICS_]: INF_PTR = CH$ASCIZ ($NML$TEXT('Characteristics '));
        [COUNTERS_]: INF_PTR = CH$ASCIZ ($NML$TEXT('Counters '));
        [EVENTS_]: INF_PTR = CH$ASCIZ ($NML$TEXT('Events '));
        [inrange, outrange] : INF_PTR = 0;
        tes;
    !
    ! Build the text to describe the status of the command 
    !

    $RSP_TEXT (CH$ASCIZ($NML$TEXT ('%/Request # %D; %A %A %A%A%N')),
               .REQ_NO,                 ! Request id number
               .CMD_PTR,                ! Pointer to command name string
               .ENT_PTR,                ! Pointer to entity name string
               .INF_PTR,                ! Pointer to info_type string
               .STS_PTR);               ! Pointer to status string

    end;				! End of FMT_HEADER
%routine ('FMT_ERROR_INFO', ENTITY_TYPE, RTN_COD, ERR_DETAIL) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    local
         ERR_LEN,                       ! Length of error message string
         ERR_PTR;                       ! Pointer to error message

    !
    ! If error detail field is present in message build format pattern
    ! to show its contents
    !

    if NEXTW_RESP                       ! Room for error detail?
    then begin                          ! Yes,
         .ERR_DETAIL = GETW (RESP_PTR);  ! Extract it

         if (.RTN_COD lss 0 and .RTN_COD gtr -128) ! Is it applicable?
	 then FMT_ERR_DETAIL (.ENTITY_TYPE, .RTN_COD, ..ERR_DETAIL);

    !
    ! Add error message text if present
    !

         if GET_ERR_MESSAGE (ERR_LEN,ERR_PTR)
         then $RSP_TEXT (',%/%#A %/%N', .ERR_LEN, .ERR_PTR);
         end;

    end;				! End of FMT_ERROR_INFO
%routine ('FMT_ERR_DETAIL', ENTITY_TYPE, RTN_COD, ERR_DETAIL) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Formats the error detail part of the message, if applicable.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - The full entity type to which this request was
!                     issued.
!	RTN_COD - The NICE return code from the response message.
!	ERR_DETAIL - The error detail value.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	$TRUE - if error detail was applicable.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

!
! The error detail field was present in the NICE response message
! so process it accordingly.
!

    if (.ERR_DETAIL eql 65535)          ! Error detail present but
    then return $FALSE;                 !  Not Applicable

    selectone .RTN_COD of
        set
        [NICE$_UPT,                     !  Unrecognized parameter type
         NICE$_IPV,                     !  Invalid parameter value
         NICE$_PNA,                     !  Parameter not applicable
         NICE$_PVL,                     !  Parameter value too long
         NICE$_PAM]:                    !  Parameter missing
            begin                       ! Display parameter type number
            local PRM_TXT_PTR;

            PRM_TXT_PTR = NML$PARAMETER_TEXT (.ENTITY_TYPE, .ERR_DETAIL);

            if .PRM_TXT_PTR neq 0
            then $RSP_TEXT (CH$ASCIZ ($NML$TEXT (',%/Parameter = %#A%N')),
                            ch$rchar_a (PRM_TXT_PTR),
                            .PRM_TXT_PTR)
            else $RSP_TEXT (CH$ASCIZ ($NML$TEXT (',%/Parameter #%D%N')),
                            .ERR_DETAIL);

            return $TRUE;
            end;

        [NICE$_URC,                     !  Unrecognized component
         NICE$_IID,                     !  Invalid identification
         NICE$_CWS]:                    !  Component in wrong state
            begin                       ! Display entity type number
            local ENT_TXT_PTR;

            if .ERR_DETAIL eql NO_ENTITY_
            then begin
                 $RSP_TEXT (CH$ASCIZ ($NML$TEXT (',%/No entity%N')));

                 return $TRUE;
                 end;

            ENT_TXT_PTR = GET_ENTITY_NAME (.ERR_DETAIL, 0);

            if .ENT_TXT_PTR neq 0
            then begin
                 $RSP_TEXT (CH$ASCIZ ($NML$TEXT (',%/Entity = %A%N')),
                            .ENT_TXT_PTR);

                 return $TRUE;
                 end;
            end;

        [NICE$_FOE,                     ! File open error
         NICE$_IFC,                     ! Invalid file contents
         NICE$_FIO]:                    ! File I/O error
            begin                       ! Display file type code
            local FIL_TXT_PTR;

            FIL_TXT_PTR = GET_FILE_ERR_TEXT (.ERR_DETAIL);

            if .FIL_TXT_PTR neq 0
            then begin
                 $RSP_TEXT (CH$ASCIZ ($NML$TEXT (',%/File = %#A%N')),
                            ch$rchar (ch$plus (.FIL_TXT_PTR, -1)),
                            .FIL_TXT_PTR);

                 return $TRUE;
                 end;
            end;

        [NICE$_MLD,                     ! Mirror link disconnected
         NICE$_MCF,                     ! Mirror connect failed
         NICE$_LLD,                     ! Listener Link Disconnected
         NICE$_LCF]:                    ! Listener link connect failed
            begin                       ! Display link fail code
            local LNK_TXT_PTR;

            LNK_TXT_PTR = GET_LINK_ERR_TEXT (.ERR_DETAIL);

            if .LNK_TXT_PTR neq 0
            then begin
                 $RSP_TEXT (CH$ASCIZ ($NML$TEXT (',%/Link Failure = %#A%N')),
                            ch$rchar (ch$plus (.LNK_TXT_PTR, -1)),
                            .LNK_TXT_PTR);

                 return $TRUE;
                 end;
            end;
        tes;

    $RSP_TEXT (CH$ASCIZ ($NML$TEXT (',%/Error detail = %D%N')), .ERR_DETAIL);

    return $TRUE;
    end;				! End of FMT_ERR_DETAIL
%routine ('FMT_ENTITY_HEADER', ENTITY_TYPE_ADDR, CODE, COMMAND) =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE_ADDR - The address of a variable containing the
!			   full entity type
!
!	CODE		 - The return code
!
!	COMMAND		 - The command code
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	ENTITY_TYPE_ADDR[ENTITY_SUB] may be filled in if needed.
!
!--

    begin

    bind
        LOGGING_CONSOLE_PTR = ch$asciz ($NML$TEXT ('Console')),
        LOGGING_FILE_PTR = ch$asciz ($NML$TEXT ('File')),
        LOGGING_MONITOR_PTR = ch$asciz ($NML$TEXT ('Monitor')),
        LOGGING_EIDS = uplit (LOGGING_CONSOLE_PTR,
                              LOGGING_FILE_PTR,
                              LOGGING_MONITOR_PTR) : vector [3];

    map 
	ENTITY_TYPE_ADDR : ref FULL_ENTITY;

    local
	 DEREF : FULL_ENTITY,
         EID_PTR,                       ! Pointer to entity id string
         EID_LEN,                       ! Entity id length
         NOD_ADR;                       ! Node address

    !
    ! Attempt to get pointer to entity id in response message. 
    ! If none exists return false.
    !

    if not GET_ENTITY_ID (NOD_ADR, EID_LEN, EID_PTR, .ENTITY_TYPE_ADDR)
    then return $FALSE;

    !
    ! Output entity line
    !

    if ((.COMMAND eql CHANGE_) or
	(.COMMAND eql ZERO_))
    then $RSP_TEXT ('%/  %N')		! Format for SET command
    else $RSP_TEXT ('%/%/%N');		! Format for SHOW command

    !
    ! Format of entity descriptor line depends on entity type
    !

    DEREF = ..ENTITY_TYPE_ADDR;

    case .DEREF[ENTITY_MAIN] from ENTITY_LO to ENTITY_HI of
        set
       [ENTITY_AREA]:
            $RSP_TEXT (CH$ASCIZ ($NML$TEXT ('Area = %M%/%N')),
                       ch$rchar (.EID_PTR));

       [ENTITY_NODE]:
            begin
            if .EID_LEN<7,1> eql 1      ! Is it Executor node?
            then begin

                 EID_LEN<7,1> = 0;      ! Clear Executor indicator

                 if .NOD_ADR<10,6> eql 0
                 then begin
                      local TEMP;
                      TEMP = NMU$NETWORK_LOCAL();
                      TEMP = GETW (TEMP);
                      NOD_ADR<10,6> = .TEMP<10,6>;
                      end;

                 $RSP_TEXT (CH$ASCIZ ($NML$TEXT ('Executor Node = %M.%M (%#A)%/%N')),
                            .NOD_ADR<10,6>,
                            .NOD_ADR<0,10>,
                            .EID_LEN,
                            .EID_PTR)
                 end
            else if .NOD_ADR eql 0
                 then $RSP_TEXT (CH$ASCIZ ($NML$TEXT ('Node = %#A%/%N')),
                                      .EID_LEN,
                                      .EID_PTR)
                 else begin

                      if .NOD_ADR<10,6> eql 0
                      then begin

                           local TEMP;
                           TEMP = NMU$NETWORK_LOCAL();
                           TEMP = GETW (TEMP);
                           NOD_ADR<10,6> = .TEMP<10,6>;
                           end;

                      $RSP_TEXT (CH$ASCIZ ($NML$TEXT ('Remote Node = %M.%M (%#A)%/%N')),
                                      .NOD_ADR<10,6>,
                                      .NOD_ADR<0,10>,
                                      .EID_LEN,
                                      .EID_PTR);
                      end;
            end;

       [ENTITY_LINE]:
            $RSP_TEXT (CH$ASCIZ ($NML$TEXT ('Line = %#A%/%N')),
                       .EID_LEN,
                       .EID_PTR);

       [ENTITY_LOGGING]:
            begin
            EID_PTR = .LOGGING_EIDS [ch$rchar (.EID_PTR) - 1];
            EID_LEN = ch$len (.EID_PTR);
            $RSP_TEXT (CH$ASCIZ ($NML$TEXT ('Logging = %#A%/%N')),
                       .EID_LEN,
                       .EID_PTR);
            end;

       [ENTITY_CIRCUIT]:
            $RSP_TEXT (CH$ASCIZ ($NML$TEXT ('Circuit = %#A%/%N')),
                       .EID_LEN,
                       .EID_PTR);

       [ENTITY_MODULE]:
            $RSP_TEXT (CH$ASCIZ ($NML$TEXT ('Module = %#A%/%N')),
                       .EID_LEN,
                       .EID_PTR);
        tes;


    if ((.COMMAND eql CHANGE_) or
	(.COMMAND eql ZERO_))
    then $RSP_TEXT ('%/%N');		! Format for SET command

    return $TRUE;
    end;				! End of FMT_ENTITY_HEADER
%routine ('GET_ERR_MESSAGE', ERR_LEN, ERR_PTR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Determines if the error message field of the NICE response message
!       exists and if so provides its length and a character pointer to it. 
!
! FORMAL PARAMETERS
!
!	ERR_LEN - The address of a variable to contain the length of the
!                 error message.
!
!       ERR_PTR - The address of a variable to contain a pointer to the
!                 error message text.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	TRUE, If error message exists. FALSE, otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    if NEXTF_RESP                       ! Is there an error message field ?
    then begin                          ! Yes...
         .ERR_LEN = GETB (RESP_PTR);    ! Get the message text length
         if ..ERR_LEN gtr 0             ! Is there any text there ?
         then begin                     ! Yes...
              .ERR_PTR = .RESP_PTR;     ! Get pointer to text
              RESP_PTR = ch$plus (.RESP_PTR,..ERR_LEN);  ! And bump past field
              return $TRUE;             ! Indicate error message present
              end;
         end;

    return $FALSE;                      ! Field not in message or no text
    end;				! End of GET_ERR_MESSAGE
%routine ('GET_ENTITY_ID', NODE_NO, EID_LEN, EID_PTR, ENTITY_TYPE_ADDR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Obtains a pointer to the entity id if one is present in the NICE
!       response message. If the entity type is node also stores the
!       node address in a variable whose address is provided as a parameter.
!
! FORMAL PARAMETERS
!
!	NODE_NO     -      The address of a variable to contain the node address
!                          if the entity type is node.
!		                   
!	EID_LEN     -      The address of a variable to contain the length of the
!                          entity id string.
!		                   
!       EID_PTR     -      The address of a variable to contain the pointer to the
!                          entity id string.
!
!       ENTITY_TYPE_ADDR - The address of a variable containing the full entity 
!		           type to which the the entity id is associated. 
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	TRUE, if the response message contains an entity id field.
!       FALSE, otherwise.
!
! SIDE EFFECTS:
!
!	If ENTITY_TYPE_ADDR is ENTITY_MODULE, 
!       then the submodule type is inserted
!
!--

    begin
	local DEREF : FULL_ENTITY;

    !
    ! Special case for length byte in node name: bit 7 means executor!
    !

    macro
        NEXTF_NODE (MAX, CNT, PTR) =
            begin
            local TEMP;

            if MAX geq (TEMP = .CNT + 1)
            then begin
                 CNT = .TEMP + (ch$rchar (PTR) and %O'177');
                 (1 eql 1)
                 end
            else (1 eql 0)
            end %;

    macro
        NEXTF_NODE_RESP =
            NEXTF_NODE (.RESP_LEN, RESP_POS, .RESP_PTR) %;

    map 
	ENTITY_TYPE_ADDR : ref FULL_ENTITY;

    DEREF = ..ENTITY_TYPE_ADDR;		! Get full entity type

    case .DEREF[ENTITY_MAIN] from ENTITY_LO to ENTITY_HI of
        set
       [ENTITY_NODE]:
            begin
            if NEXTW_RESP               ! Is the node address present?
            then begin                  ! Yes...
                 .NODE_NO = GETW (RESP_PTR); ! Get the node address value
                 if NEXTF_NODE_RESP     ! Is the node name present?
                 then begin             ! Yes...
                      local PTR;

                      .EID_LEN = GETB (RESP_PTR); ! Get length of node name
                      if ..EID_LEN gtr 0
                      then begin
                           PTR = .RESP_PTR; ! Save pointer to node name
                           RESP_PTR = ch$plus (.RESP_PTR, ! Bump past it
                                               ..EID_LEN and %O'177');
                           .EID_PTR = .PTR; ! Return the pointer to node name
                           end
                      else .EID_PTR = 0;
                      end
                 else begin
                      .EID_LEN = 0;
                      .EID_PTR = 0;
                      end;

                 return $TRUE;
                 end
            else begin
                 .NODE_NO = -1;
                 .EID_LEN = 0;
                 .EID_PTR = 0;

                 return $FALSE ;
                 end;
            end;

       [ENTITY_LINE,
         ENTITY_CIRCUIT,
         ENTITY_MODULE]:
            begin
            if NEXTF_RESP               ! Is the id string present?
            then begin                  ! Yes...
                 local PTR;

                 .EID_LEN = GETB (RESP_PTR); ! Get length of id string
                 if ..EID_LEN gtr 0
                 then begin
                      PTR = .RESP_PTR;  ! Save pointer to id string
                      RESP_PTR = ch$plus (.RESP_PTR, ! Bump past it
                                          ..EID_LEN);
                      .EID_PTR = .PTR;  ! Return the pointer to id string
	              if ..ENTITY_TYPE_ADDR eql ENTITY_MODULE then
	              begin				     ! Get submodule type from response
	                   if ..EID_LEN gtr 0 then
	                   begin
	                     local
	                        SEID_STRING : CH$SEQUENCE [80], ! String storage for subentity id.
	                        SEID_PTR,			     ! Pointer to string.
	                        SEID : FULL_ENTITY;
	              
 	                        SEID_PTR = ch$ptr (SEID_STRING,,7);	! Convert to 7 bit bytes.
 	                        ch$move (..EID_LEN, ..EID_PTR, .SEID_PTR);
	              
	                        SEID = ..ENTITY_TYPE_ADDR;		! Get subentity type
	                        SEID[ENTITY_SUB] = NML$GET_SUBENTITY_ID (..EID_LEN, .SEID_PTR);
	                        .ENTITY_TYPE_ADDR = .SEID;
	                        end
	                   end;
                      end
                 else .EID_PTR = 0;

                 return $TRUE;
                 end
            else begin
                 .EID_LEN = 0;
                 .EID_PTR = 0;

                 return $FALSE ;
                 end;
            end;

       [ENTITY_AREA]:
            begin
            if NEXTW_RESP               ! Is the area id present?
            then begin                  ! Yes...
		 if GETB (RESP_PTR) eql 0 then ! Get format byte. Is id present ?
		 begin
                     .EID_PTR = .RESP_PTR;  ! Yes. Set pointer to id
                     GETB (RESP_PTR);       ! Bypass the id.
		     end
		 else
		     .EID_PTR = 0;	    ! No.   
                 return $TRUE;
                 end
            else begin
                 .EID_LEN = 0;
                 .EID_PTR = 0;

                 return $FALSE;
                 end;
            end;
       [ENTITY_LOGGING]:
            begin
            if NEXTB_RESP               ! Is the id byte present?
            then begin                  ! Yes...
                 .EID_PTR = .RESP_PTR;  ! Set pointer to id
                 .EID_LEN = 1;          ! and set length non-zero.
                 GETB (RESP_PTR);       ! bypass the id.

                 return $TRUE;
                 end
            else begin
                 .EID_LEN = 0;
                 .EID_PTR = 0;

                 return $FALSE;
                 end;
            end;
        tes;

    end;				! End of GET_ENTITY_ID
%routine ('GET_LINK_ERR_TEXT', ERR_DETAIL) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Determines if the error message field of the NICE response message
!       exists and if so provides its length and a character pointer to it. 
!
! FORMAL PARAMETERS
!
!	ERR_LEN - The address of a variable to contain the length of the
!                 error message.
!
!       ERR_PTR - The address of a variable to contain a pointer to the
!                 error message text.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	TRUE, If error message exists. FALSE, otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    case .ERR_DETAIL from 0 to 16 of
        set
        $NICE$ERR_CASES ($LINK_DETAIL_ERRORS);

        [inrange,
         outrange]: 0;
        tes

    end;				! End of GET_LINK_ERR_TEXT
%routine ('GET_FILE_ERR_TEXT', ERR_DETAIL) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Determines if the error message field of the NICE response message
!       exists and if so provides its length and a character pointer to it. 
!
! FORMAL PARAMETERS
!
!	ERR_LEN - The address of a variable to contain the length of the
!                 error message.
!
!       ERR_PTR - The address of a variable to contain a pointer to the
!                 error message text.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	TRUE, If error message exists. FALSE, otherwise.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    case .ERR_DETAIL from 0 to 6 of
        set
        $NICE$ERR_CASES ($FILE_DETAIL_ERRORS);

        [inrange,
         outrange]: 0;
        tes

    end;				! End of GET_FILE_ERR_TEXT
%routine ('FMT_RESPONSE_DATA', ENTITY_TYPE, CMD_CODE, REQ) =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin
            
    local
         DATA_ID: block [1] field (DATA_ID_FIELDS);

    map
       REQ: ref REQUEST_BLOCK;          ! Make fields addressable

    REQ[RB_RESPONSE_DATA] = 1;          ! Set flag non-zero
    if NEXTW_RESP                       ! Any data following return code ?
    then begin                          ! Yes
         local PARAMETER, NEXT;

         PARAMETER = NEXT = -1;         ! Initialize parameter numbers

         do begin
            DATA_ID = GETW (RESP_PTR);  ! Get the data id of this data entry
            NEXT = .DATA_ID[DI_PARMNO]; ! Get parameter number

            if .DATA_ID[DI_TYPE] eql 1
            then begin                  ! Counter field
                 if .DATA_ID[DI_WIDTH] neq 0
                 then FMT_COUNTER (.ENTITY_TYPE, .DATA_ID)
                 else $INTERNAL_ERROR$ ('Invalid counter width in data id');
                 end
            else begin                  ! Parameter field
                 if (.DATA_ID[DI_WIDTH] eql 0)
                 and (.DATA_ID[DI_MAPPED] eql 0)
                 then FMT_PARAMETER (.ENTITY_TYPE,
                                     .DATA_ID,
                                     (.NEXT eql .PARAMETER) and
                                      not ((.ENTITY_TYPE eql ENTITY_LOGGING)
                                           and (.PARAMETER eql 201)))
                 else $INTERNAL_ERROR$ ('Non-zero reserved fields in data id');
                 end;

            PARAMETER = .NEXT;          ! Remember current parameter number
            end
         while NEXTW_RESP;
         end
    else begin                          ! No
         if (.CMD_CODE eql READ_)       ! Function is READ
         then $RSP_TEXT ($NML$TEXT ('%/  No Information%/')); ! then that's it.
         end;

    !
    ! Terminate the text string with a null byte.
    !

    $RSP_TEXT ('');                    ! Terminate with null

    return $TRUE;
    end;				! End of FMT_RESPONSE_DATA

%global_routine('NCP$EVENT_FMT_DATA' , EVENT_CLASS_ENTITY,
                                         EVENT_ENTITY,
                                         DSP_PTR,
                                         DSP_LENGTH,
                                         DSP_MAX_LENGTH,
                                         MSG_LENGTH,
                                         MSG_POS,
                                         MSG_PTR) : novalue =

!++
!
! Functional description:
!
!    This routine formats an event parameter.
!
!    Event parameters come in special messages (event messages) and not in
!    NICE messages. They are based on event class (if it is an event parameter)
!    and not on entity type like NICE parameters. On the other hand: event
!    counters are linked to entity type.
!
!    The display format is the same as for NICE parameters and counters.
!    (Event parameters are displayed by the console logger). At the time
!    NCPRSP was coded noone thought of an entry point, or indeed even of
!    a database for events. Therefore this routine exists, and I'm not proud
!    of it.
!
!    It is done in the following way: the event parameters are based on
!    event class. So there is an additional set of entities defined in
!    NMARCH; one entity per event class. The NMARCH/NMLPRM database is
!    generated to contain these extra entity classes, and the consequence
!    is that NCPRSP routines will be able to format event parameters.
!
!    Since event messages do not use request blocks, and do not want a
!    formatted display with headers and so forth, this level of entry
!    into NCPRSP was decided. Request blocks are not used below this
!    level.
!
!    Also, we have to supply our own pointers to our buffers.
!
! Formal parameters:
!
!    EVENT_CLASS_ENTITY    The "event entity" that answers to the events
!                          event class (....)
!
!    EVENT_ENTITY     The event entity (for event counters)
!
!    DSP_PTR          Address of a character pointer to output text buffer
!
!    DSP_LENGTH       # of characters written to output text buffer
!
!    DSP_MAX_LENGTH   Maximum # of characters in output text buffer
!
!    MSG_LENGTH       Maximum message length
! 
!    MSG_POS          Current # of characters read in message buffer
!
!    MSG_PTR          Address of character pointer to message buffer
!
!--

   begin

   local DATA_ID : block [1] field (DATA_ID_FIELDS);

   ! Move all pointers to their NCPRSP equivalent
   TEXT_PTR = ..DSP_PTR;
   TEXT_LENGTH = TEXT_BUFFER_LENGTH - (.DSP_MAX_LENGTH - .DSP_LENGTH);

   RESP_LEN = .MSG_LENGTH;
   RESP_POS = .MSG_POS;
   RESP_PTR = ..MSG_PTR;

   ! Loop while there are more parameters
   while NEXTW_RESP do
         begin

         DATA_ID = GETW(RESP_PTR);      ! Get data ID
         if .DATA_ID[DI_TYPE] eql 1
         then begin                     ! Counter
              if .DATA_ID[DI_WIDTH] neq 0
              then FMT_COUNTER(.EVENT_ENTITY, .DATA_ID)
              else exitloop;
              end
         else begin                     ! Parameter
              if (.DATA_ID[DI_WIDTH] eql 0)
              and (.DATA_ID[DI_MAPPED] eql 0)
              then FMT_PARAMETER(.EVENT_CLASS_ENTITY, .DATA_ID, 0)
              else exitloop;
              end;
         end;                           ! End while loop

   .DSP_PTR = .TEXT_PTR;                ! Reset our pointers
   .MSG_PTR = .RESP_PTR;

   return;

   end;                                 ! End of NCP$EVENT_FMT_DATA

%routine ('FMT_COUNTER', ENTITY_TYPE, DATA_ID) =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin
            
    map
       DATA_ID: block [1] field (DATA_ID_FIELDS); ! Data ID byte

    local
         CNTR_NO,                       ! Counter type number
         BITMAP,                        ! Counter bit map
         VALUE,                         ! Counter value
         MAX_VALUE;                     ! Maximum counter value

    CNTR_NO = .DATA_ID[DI_CNTRNO];      ! Get counter number
    BITMAP = 0;
    VALUE = 0;
    MAX_VALUE = 0;

    if .DATA_ID[DI_MAPPED]              ! If mapped counter 
    then begin
         if NEXTW_RESP
         then BITMAP = GETW (RESP_PTR); ! get the bit map
!	 else error
         end;

    case .DATA_ID[DI_WIDTH] from 1 to 3 of
        set
        [1]:                            ! 8 bit counter
            if NEXTB_RESP
            then begin
                 VALUE = GETB (RESP_PTR);
                 MAX_VALUE = (1^8) - 2;
                 end;

        [2]:                            ! 16 bit counter
            if NEXTW_RESP
            then begin
                 VALUE = GETW (RESP_PTR);
                 MAX_VALUE = (1^16) - 2;
                 end;

        [3]:                            ! 32 bit counter
            begin
            NEXTW_RESP;                 ! Account for first two bytes
            if NEXTW_RESP               ! And second two bytes
            then begin
                 VALUE = GETN (RESP_PTR,4);
                 MAX_VALUE = (1^32) - 2;
                 end;
            end;

        [outrange]:                     ! reserved
            $INTERNAL_ERROR$ ('Invalid bit counter width');
        tes;

    INTERPRET_COUNTER (.ENTITY_TYPE, .CNTR_NO, .BITMAP, .VALUE, .MAX_VALUE)

    end;				! End of FMT_COUNTER
%routine ('INTERPRET_COUNTER', ENTITY_TYPE, CNTR_NO, BITMAP, VALUE, MAX_VALUE) =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
! 
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    local
         CNTR_TEXT_PTR;                 ! Pointer to text of counter name

!
! Get text string for counter (or 0 if counter not found);
!

    CNTR_TEXT_PTR = NCP$COUNTER_TEXT (.ENTITY_TYPE, .CNTR_NO);

!
! Format a text line for the counter
!

    $RSP_TEXT ((if .VALUE leq .MAX_VALUE ! Format unknown counter
                then (if .CNTR_TEXT_PTR eql 0
                      then CH$ASCIZ ($NML$TEXT ('%/  %D%16T%+Counter #%D%N'))
                      else CH$ASCIZ ('%/  %D%16T%A%N'))
                else (if .CNTR_TEXT_PTR eql 0
                      then CH$ASCIZ ($NML$TEXT ('%/ >%D%16T%+Counter #%D%N'))
                      else CH$ASCIZ ('%/ >%D%16T%A%N'))),
               min (.VALUE,.MAX_VALUE),
               .CNTR_TEXT_PTR,
               .CNTR_NO);

!
! Now, if there is a bit map, format a text line for each bit
!

    if .BITMAP nequ 0
    then begin
         $RSP_TEXT (CH$ASCIZ ($NML$TEXT (', including:%N')));
         incr B from 0 to %bpval-1
         do begin
            if .BITMAP
            then begin
                 CNTR_TEXT_PTR = NCP$BIT_TEXT(.ENTITY_TYPE,.CNTR_NO,.B);
                 $RSP_TEXT ((if .CNTR_TEXT_PTR eqlu 0
                             then CH$ASCIZ ($NML$TEXT ('%/%28T%+Bit #%D%N'))
                             else CH$ASCIZ ('%/%28T%A%N')),
                            .CNTR_TEXT_PTR,
                            .B);
                 end;

            BITMAP = .BITMAP ^ -1;
            if .BITMAP eqlu 0
            then exitloop;
            end;
         end;

    return .TEXT_LENGTH;
    end;				! End of INTERPRET_COUNTER
%routine ('FMT_PARAMETER', ENTITY_TYPE, DATA_ID, CONTINUE) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Formats the text for a single parameter returned in the
!       data portion of a NICE response message.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - The full entity type to which the parameter is
!                     associated.
!	DATA_ID     - The DATA ID value which precedes the parameter.
!       CONTINUE    - Indicate if this parameter is identical to a previous
!                     one. If this value is true, the parameter name text
!                     is not printed and only the values are displayed.
!
! IMPLICIT INPUTS
!
!	REQ - Address of the Request Block, which contains among other
!             things, a pointer to the NICE response message being
!             processed. The pointer must point at the DATA TYPE byte
!             for this parameter.
!
!	RESP_PTR - pointer to the response message
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin
            
    map
       ENTITY_TYPE : FULL_ENTITY,
       DATA_ID : block [1] field (DATA_ID_FIELDS); ! Data ID byte

    local
         PARAMETER,                     ! Parameter type number
         DATA_TYPE: block [1] field (DATA_TYPE_FIELDS);

    PARAMETER = .DATA_ID[DI_PARMNO];    ! Get the parameter number

    ! If the parameter number is identical to a previous one,
    ! display ", " on the same output line;
    ! otherwise lookup parameter number and output parameter name text string.
    ! If parameter lookup fails display decimal value of parameter number.

    if .CONTINUE
    then $RSP_TEXT (', %N')
    else begin
         local FORMAT, LEXICAL;

         LEXICAL = NML$PARAMETER_TEXT (.ENTITY_TYPE, .PARAMETER);
         if .LEXICAL eql 0              ! No name text for parameter
         then FORMAT = CH$ASCIZ ($NML$TEXT ('%/%2+  Parameter #%D = %N'))
         else if NML$INFORMATION (.ENTITY_TYPE, .PARAMETER, QUALIFIER_)
              then FORMAT = CH$ASCIZ ('%2/  %#A = %N') ! Qualifier
              else FORMAT = CH$ASCIZ ('%/  %#A = %N'); ! Not qualifier

         $RSP_TEXT ((.FORMAT),
                    ch$rchar_a (LEXICAL),
                    .LEXICAL,
                    .PARAMETER);
         end;

    if NEXTB_RESP
    then DATA_TYPE = GETB (RESP_PTR);   ! Get the data type bit map byte

    if .DATA_TYPE[DT_CODED] eql 0       ! Uncoded fields
    then FMT_UNCODED_FIELD (.ENTITY_TYPE, .PARAMETER, .DATA_TYPE)
    else begin                          ! Coded fields
         if .DATA_TYPE[DT_FIELDS] eql 0 ! Single field
         then FMT_SINGLE_CODED_FIELD (.ENTITY_TYPE, .PARAMETER, .DATA_TYPE)
         else begin                     ! Multiple fields
              local FORMAT: block [1] field (DATA_TYPE_FIELDS),
                    PREFIX, SUFFIX, FIELD_LENGTH, EVENT_SRC_NODE;

              PREFIX = 0;               ! Initially, no prefix string
              SUFFIX = 0;               ! nor suffix string
              FIELD_LENGTH = .DATA_TYPE[DT_NUMBER]; ! Get number of fields
              EVENT_SRC_NODE = $false;  ! Initially, not doing event source
              FORMAT = NML$DATA_TYPE (.ENTITY_TYPE, .PARAMETER); ! Get
              FORMAT = .FORMAT[DT_NUMBER]; ! parameter format index

              while (FIELD_LENGTH = .FIELD_LENGTH - 1) geq 0
              do begin                  ! Loop for each field

                 if NEXTB_RESP          ! Get the data type byte
                 then DATA_TYPE = GETB (RESP_PTR);

                 selectone .FORMAT of
                     set
                     [CMN] :            ! Node format
                         if .DATA_TYPE eql (1^6)
                         then begin     ! Put node name in parenthesis
                              PREFIX = CH$ASCIZ (' (%N');
                              SUFFIX = CH$ASCIZ (')%N');
                              end;
                     [CMO] :            ! Object format
                         if .DATA_TYPE eql (1^6)
                         then begin     ! Put object name in parenthesis
                              PREFIX = CH$ASCIZ (' (%N');
                              SUFFIX = CH$ASCIZ (')%N');
                              end;
                     [CMV] :            ! Version format
                         if .PREFIX neq 0 ! Change seperator to '.'
                         then PREFIX = CH$ASCIZ ('.%N');
                     [CM2] :            ! Range format
                         if .PREFIX neq 0 ! Change seperator to '-'
                         then PREFIX = CH$ASCIZ ('-%N');
                     [CME] :            ! Event format
                         begin

                         selectone .DATA_TYPE of
                             set

                             [%O'002'] : ! Event class or node number
                                 begin
                                 if .FIELD_LENGTH eql 3 ! Must be source node
                                 then begin
                                      EVENT_SRC_NODE = $true;
                                      PREFIX = ch$asciz(' = %N');
                                      SUFFIX = 0;
                                      end
                                 else begin ! Must be event class
                                      EVENT_SRC_NODE = $false;
                                      PREFIX = ch$asciz(') %N');
                                      SUFFIX = ch$asciz('.%N');
                                      end;
                                 end;

                             [%O'100'] : ! AI image
                                 begin
                                 if .EVENT_SRC_NODE eql $true
                                 then begin
                                      PREFIX = ch$asciz(' (%N');
                                      SUFFIX = ch$asciz(')%N');
                                      end
                                 else begin
                                      PREFIX = ch$asciz(' = %N');
                                      SUFFIX = 0;
                                      end;
                                 end;

                             [%O'201'] : ! Entity format
                                 begin
                                 PREFIX = ch$asciz('(Source %N');
                                 SUFFIX = 0;
                                 end;

                             [%O'202'] : ! Area number
                                 begin
                                 PREFIX = ch$asciz(' = %N');
                                 SUFFIX = 0;
                                 end;

                             [%O'040' ,otherwise] :
                                 PREFIX = SUFFIX = 0;

                             tes;

                             end;       ! End select CME

                     [CMU,otherwise] : ! Unanticipated
                         0;
                     tes;

                 if .PREFIX neq 0       ! Output the prefix separator string
                 then $RSP_TEXT ((.PREFIX));

                 if .DATA_TYPE[DT_CODED] eql 1 ! Coded field ?
                 then begin
                      if .DATA_TYPE[DT_FIELDS] eql 0 ! Single field ?
                      then FMT_SINGLE_CODED_FIELD (.ENTITY_TYPE,
                                                   .PARAMETER,
                                                   .DATA_TYPE)
                      else begin
                           $INTERNAL_ERROR$ ('Invalid Parameter format, ',
                                             'DATA TYPE contains multip',
                                             'le fields within a multip',
                                             'le field');
                           end;
                      end
                 else selectone .FORMAT of
                          set
                          [CMN] :
                              if .DATA_TYPE eql (0^4 + 2)
                              then FMT_NODE_ID_FIELD (.ENTITY_TYPE,
                                                      .PARAMETER)
                              else FMT_UNCODED_FIELD (.ENTITY_TYPE,
                                                      .PARAMETER,
                                                      .DATA_TYPE);
                          [CME] :
                              if .DATA_TYPE eql %O'040'
                              then FMT_EVENT_LIST_FIELD ()
                              else if (.DATA_TYPE eql %O'002')
                                   and (.EVENT_SRC_NODE eql $true)
                                   then FMT_NODE_ID_FIELD(.ENTITY_TYPE,
                                                          .PARAMETER)
                                   else FMT_UNCODED_FIELD (.ENTITY_TYPE,
                                                           .PARAMETER,
                                                           .DATA_TYPE);

                          [otherwise] :
                              FMT_UNCODED_FIELD (.ENTITY_TYPE, .PARAMETER, .DATA_TYPE);
                          tes;

                 if .SUFFIX neq 0
                 then begin
                      $RSP_TEXT ((.SUFFIX));
                      SUFFIX = 0;
                      end;

                 PREFIX = CH$ASCIZ (' / %N');  ! Default separator
                 end;
              end;
         end;

    end;				! End of FMT_PARAMETER
%routine ('FMT_SINGLE_CODED_FIELD', ENTITY_TYPE, PARM_NO, DATA_TYPE) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Formats the text output for a single coded parameter value.
!       The text is either the name for a recognized coded value or
!       the octal value itself.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - The full entity type that the parameter refers to
!
!	PARM_NO	-     The parameter number under discussion
!
!	DATA_TYPE -   The data type of the parameter
!
! IMPLICIT INPUTS
!
!	TEXT_PTR, TEXT_LENGT, RESP_PTR.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	Builds response text in the usual manner.
!
!--

    begin

    map
       ENTITY_TYPE : FULL_ENTITY,
       DATA_TYPE: block [1] field (DATA_TYPE_FIELDS);

    local
         CODED,                          ! Pointer to coded name text
         CODED_LENGTH,                   ! Length of coded name text
         FIELD_LENGTH,                  ! Length of data
         DATA;                          ! Value of coded data

    FIELD_LENGTH = .DATA_TYPE[DT_NUMBER]; ! Get number of bytes
    if NEXTN_RESP (.FIELD_LENGTH)
    then DATA = GETN (RESP_PTR, .FIELD_LENGTH) ! Get coded value
    else $INTERNAL_ERROR$ ('Message short terminated');

    !
    ! Lookup parameter number and output coded text string.
    ! If parameter lookup fails display the code in octal.
    !

    CODED = NML$CODED_TEXT (.ENTITY_TYPE, .PARM_NO, .DATA);

    ! I don't see any other way than the following crock. I couldnt insert
    ! a -1 (377) value in the table since it uses negative offsets for other
    ! things....therefore this special test to make events print nice.
    if .ENTITY_TYPE eql ENTITY_LOGGING
       and .PARM_NO eql 201
       and .DATA_TYPE eql %O'201'
       and .DATA eql %O'377'
    then CODED = ch$plus(ch$ascic('= any'),-1);

    ! Have to special case network management event parameter 1 because
    ! it's coded value is the NICE return code.
    if .ENTITY_TYPE eql ENTITY_EVENT_0
       and .PARM_NO eql 1
    then CODED = ch$plus(
         (if .DATA eql 0
          then ch$ascic( 'Requested')
          else if .DATA eql NICE$_SUC then ch$ascic( 'Success')
          else NCP$GET_ERR_TEXT (.DATA)), -1);

    if .CODED eql 0
    then $RSP_TEXT ('%O%N' , .DATA)
    else begin
         CODED_LENGTH = ch$rchar_a (CODED);
         $RSP_TEXT ('%#A%N' , .CODED_LENGTH, .CODED);
         end;

    end;				! End of FMT_SINGLE_CODED_FIELD
%routine ('FMT_UNCODED_FIELD', ENTITY_TYPE, PARM_NO, DATA_TYPE) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Formats the text output for an uncoded parameter value,
!       an AI field or a number.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - The full entity type that the parameter refers to
!
!	PARM_NO	-     The parameter number under discussion
!
!	DATA_TYPE -   The data type of the parameter
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	TEXT_PTR, TEXT_LENGTH, RESP_PTR.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	Builds response text in the usual manner.
!
!--

    begin

    map
       ENTITY_TYPE : FULL_ENTITY,
       DATA_TYPE: block [1] field (DATA_TYPE_FIELDS);

    local
         FIELD_LENGTH,                  ! Length of data for ASCII or binary
         BINARY_FORMAT,                 ! Format value if binary
         FMT_PTR,                       ! Pointer to text output format
         DATA;                          ! Binary value or pointer to ASCII

    if .DATA_TYPE[DT_FTYPE] eql 1
    then begin                          ! ASCII image field
         if .DATA_TYPE[DT_NUMBER] eql 0
         then begin
              if NEXTF_RESP
              then begin
                   FIELD_LENGTH = GETB (RESP_PTR); ! Get I-field length
                   DATA = .RESP_PTR;    ! Pointer to ASCII text in message
                   RESP_PTR = ch$plus (.RESP_PTR,.FIELD_LENGTH);  
                   $RSP_TEXT ('%#A%N', .FIELD_LENGTH, .DATA);
                   end
              else $INTERNAL_ERROR$ ('Response short terminated')
              end
         else $INTERNAL_ERROR$ ('Non-zero reserved field in data type')
         end
    else begin                          ! Binary number
         FIELD_LENGTH = .DATA_TYPE[DT_LENGTH];
         BINARY_FORMAT = .DATA_TYPE[DT_FORMAT];

         if .FIELD_LENGTH eql 0
         then begin                     ! Image binary field
              if NEXTB_RESP
              then FIELD_LENGTH = GETB (RESP_PTR);

              if .FIELD_LENGTH gtr 0
              then begin
                   if NEXTN_RESP (.FIELD_LENGTH)
                   then begin
                        DATA = .RESP_PTR; ! Save pointer to binary string
                        GETN (RESP_PTR, .FIELD_LENGTH); ! Get data field
                        case .BINARY_FORMAT from 0 to 3 of 
                            set
                            [0]:                  ! Unsigned decimal
                                FMT_PTR = CH$ASCIZ ('%#M%N');

                            [1]:                  ! Signed decimal
                                FMT_PTR = CH$ASCIZ ('%#D%N');

                            [2]:                  ! Hexadecimal
                                FMT_PTR = CH$ASCIZ ('%#K%N');

                            [3]:                  ! Octal
                                FMT_PTR = CH$ASCIZ ('%#O%N');
                            tes;

                        $RSP_TEXT ((.FMT_PTR), .FIELD_LENGTH, .DATA);
                        end;
                   end
              else $RSP_TEXT ('No Information%N');
              end
         else begin                     ! Fixed binary field
              if NEXTN_RESP (.FIELD_LENGTH)
              then begin
                   if .FIELD_LENGTH leq %bpval/8
                   then begin
                        DATA = GETN (RESP_PTR,.FIELD_LENGTH);
                        case .BINARY_FORMAT from 0 to 3 of 
                            set
                            [0]:                  ! Unsigned decimal
                                FMT_PTR = CH$ASCIZ ('%M%N');

                            [1]:                  ! Signed decimal
                                FMT_PTR = CH$ASCIZ ('%D%N');

                            [2]:                  ! Hexadecimal
                                FMT_PTR = CH$ASCIZ ('%H%N');

                            [3]:                  ! Octal
                                FMT_PTR = CH$ASCIZ ('%O%N');
                            tes;

                        $RSP_TEXT ((.FMT_PTR), .DATA);
                        end
                   else begin
			bind NL = 1;
                        RESP_PTR = ch$plus (.RESP_PTR,.FIELD_LENGTH);
                        case .BINARY_FORMAT from 0 to 3 of 
                            set
                            [0]:                  ! Unsigned decimal
                            %( N.B. - There is no way to output a byte string
                               as decimal so fake these for now. )%
                                FMT_PTR = CH$ASCIZ ('%#B %N');

                            [1]:                  ! Signed decimal
                                FMT_PTR = CH$ASCIZ ('%#B %N');

                            [2]:                  ! Hexadecimal
                                FMT_PTR = CH$ASCIZ ('%#K%N');

                            [3]:                  ! Octal
                                FMT_PTR = CH$ASCIZ ('%#B %N');
                            tes;

			incr N from 1 to .FIELD_LENGTH do
			    begin
                            DATA = ch$plus(.RESP_PTR, -.N);
                            $RSP_TEXT ((.FMT_PTR), NL, .DATA);
                            end;
                        end;
                   end
              end
         end

    end;				! End of FMT_UNCODED_FIELD
%routine ('FMT_NODE_ID_FIELD', ENTITY_TYPE, PARAMETER) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Formats the text output for a node id.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - The entity type to which the parameter is associated.
!       PARAMETER   - The parameter number
!
! IMPLICIT INPUTS
!
!	RSP_PTR, TEXT_PTR, TEXT_LENGTH
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	Builds response text in the usual manner.
!
!--

    begin

    map
       ENTITY_TYPE : FULL_ENTITY;

    local
         NOD_ADR;                       ! Binary value or pointer to ASCII

    if NEXTW_RESP
    then begin
         NOD_ADR = GETW (RESP_PTR);

         if .NOD_ADR<10,6> eql 0
         then begin
              local TEMP;
              TEMP = NMU$NETWORK_LOCAL();
              TEMP = GETW (TEMP);
              NOD_ADR<10,6> = .TEMP<10,6>;
              end;

         if .NOD_ADR<0,10> neq 0
         then begin

              $RSP_TEXT ('%M.%M%N', .NOD_ADR<10,6>, .NOD_ADR<0,10>);

              ! If 'event entity' and not sink node parameter
              if (.ENTITY_TYPE[ENTITY_MAIN] geq EVENT_ENTITY_BASE)
                 and (.PARAMETER neq 200)
              then begin

                   local TEMP :
                           vector [ch$allocation(NODE_ID_BUFFER_LENGTH,8)],
                         TEMP2 :
                           vector [ch$allocation(NODE_ID_BUFFER_LENGTH,8)],
                         IN_PTR,
                         SAV_PTR,
                         OUT_PTR,
                         NODE_LEN;

                   SAV_PTR = IN_PTR = ch$ptr (TEMP,,8);
                   OUT_PTR = ch$ptr (TEMP2,,8);

                   ! Note: NML$CONVERT_ENTITY_ID has special format of node ID
                   PUTB (0, IN_PTR);
                   PUTW (NOD_ADR, IN_PTR);
                   if NML$CONVERT_ENTITY_ID(
                                   ENTITY_NODE,
                                   SAV_PTR,
                                   .OUT_PTR)
                   then begin
                        OUT_PTR = ch$ptr (TEMP2,2,8);
                        NODE_LEN = GETB (OUT_PTR);
                        $RSP_TEXT (' (%#A) %/%N', .NODE_LEN, .OUT_PTR);
                        end;
                   end;
              end;                                 
         end;
    end;				! End of FMT_NODE_ID_FIELD

%routine('FMT_EVENT_LIST_FIELD') : novalue =

!++
!
! Functional description:
!
!       Formats the text output for an event list
!
! Formal parameters:
!
!       None
!
! Implicit inputs:
!
!       RSP_PTR, TEXT_PTR, TEXT_LENGTH
!
! Routine value:
!
!       None
!
! Side effects:
!
!       Builds response text in the usual manner.
!
!--

   begin

   local
       COUNT,                           ! Count of event "bytes"
       FILTER_BYTE,                     ! Holds filter bytes
       FILTER_PTR,                      ! Pointer to filter
       FILTER: vector[2],               ! Holds filter
       I,                               ! Loop index
       START,                           ! Start index of event item
       BUGFIX;                          ! To circumvent BLISS bug

   if NEXTB_RESP
   then begin
        COUNT = GETB(RESP_PTR);         ! Get count of event bytes
        if NEXTN_RESP(.COUNT)
        then begin
             FILTER[0] = 0;             ! Clear filter
             FILTER[1] = 0;
	     FILTER_PTR = ch$ptr (FILTER, 0, 1);
             incr I from 0 to .COUNT - 1 do
		  begin
		      FILTER_BYTE = GETB(RESP_PTR);
		      incr J from 0 to 7 do
			  ch$wchar_a (ch$rchar(ch$ptr(FILTER_BYTE, 35-.J, 1)),
				      FILTER_PTR);
		  end;

             ! Now step through the bits of the filter. START is -1 if
             ! we are currently NOT seeing a filter. If START is >= 0 then
             ! we ARE seeing a filter, and START has the starting bit
             ! position = event type number. When bits turn from 1 to 0,
             ! the events that have been collected are output and START is
             ! reset to -1.
             !
             ! Note: one may believe the loop is looping once too much.
             ! However that is actually an ugle trick to force out any
             ! collected events at the end. The "extra" bit we read will
             ! be zero since FILTER was cleared; and => a collected event
             ! will be forced out by the transition 1 -> 0......

             START = -1;                ! Initial value: no events seen
	     FILTER_PTR = ch$ptr (FILTER, 0, 1);
             incr I from 0 to (8 * .COUNT) do
                  begin
                  if ch$rchar_a (FILTER_PTR) eql 1
                  then begin
                       if .START eql -1 then START = .I;
                       end
                  else begin
                       if .START neq -1
                       then begin
                            ! The BUGFIX variable below is because BLISS
                            ! failed to compile correctly when the common
                            ! subexpression .I-1 was used where BUGFIX is
                            ! now....
                            BUGFIX = .I - 1;

                            if .BUGFIX eql .START ! Just a single event
                            then $RSP_TEXT(ch$asciz($NML$TEXT('%D %N')),
                                           .START)
                            else $RSP_TEXT(ch$asciz($NML$TEXT('%D-%D %N')),
                                           .START, .BUGFIX);
                            START = -1; ! Reset
                            end;
                       end;
                  end;
             end;
        end;
   end;                                 ! End of FMT_EVENT_LIST_FIELD

%routine ('FMT_TABULAR_HEADER', ENTITY_TYPE, SELECTOR) =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE  - The full entity type 
!       SELECTOR     - information type being displayed
!
! IMPLICIT INPUTS
!
!	HDR_TABLE - The tabular response format table
!
! ROUTINE VALUE:
!
!	$true - if tabular response is defined for this entity/selector
!       combination, otherwise $false.
!
! SIDE EFFECTS:
!
!	Sets up the globals HDR_CONTROL and HDR_ADDR.
!
!--

    begin
    map 
	ENTITY_TYPE : FULL_ENTITY;

    begin
    local HDR: ref HDR_BLOCK;
    HDR = HDR_TABLE;
    HDR_ADDR = 0;
    decr HDR_CNT from $NCP$HDR_COUNT ($NCP$TABULAR_FORMATS) to 1 do
        begin
        if (.ENTITY_TYPE[ENTITY_MAIN] eql .HDR[HDR_ENTITY]) and
           (.SELECTOR eql .HDR[HDR_INFORMATION_TYPE])
        then begin
             HDR_ADDR = .HDR;
             HDR_CONTROL = 1;
             if .ENTITY_TYPE[ENTITY_MAIN] eql ENTITY_NODE then HDR_CONTROL = .HDR_CONTROL + 1;
             return $true
             end;
        HDR = vector [.HDR, HDR_SIZE];
        end;
    end;
    $false
    end;				! End of FMT_TABULAR_HEADER
%routine ('FMT_TABULAR_DATA', REQ) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	REQ  - address of request block.
!
! IMPLICIT INPUTS
!
!	TEXT_PTR, TEXT_LENGTH, RESP_PTR.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	Builds response message in the usual manner.
!
!--

    begin

    map
       REQ: ref REQUEST_BLOCK;          ! Make fields addressable

    own
        LAST_PTR;

    local
         DATA_ID: block [1] field (DATA_ID_FIELDS),
         LINE_PTR;

    REQ[RB_RESPONSE_DATA] = 1;          ! Set flag non-zero
!Insert header
    $RSP_TEXT (ch$ptr (.HDR_ADDR[HDR_HEADER]));
    SEND_PTR = .TEXT_PTR;
    LAST_PTR = LINE_PTR = .TEXT_PTR;
    TEXT_PTR = ch$fill (%c' ', .HDR_ADDR[HDR_WIDTH], .TEXT_PTR);
    begin                          ! Insert the entity
    local PRM: ref PRM_BLOCK,
          WORK_PTR, WORK_LEN;

    PRM = .HDR_ADDR[HDR_PARAMETER_LIST];
    WORK_PTR = 0;

    decr PRM_CNT from .vector[.PRM, -1]/PRM_SIZE to 1 do
        begin                      ! Find matching parameter position
        if .PRM[PRM_NUMBER] eql -1
        then exitloop WORK_PTR = .TEXT_PTR; ! Found!!!
        PRM = vector [.PRM, PRM_SIZE];
        end;

    if .WORK_PTR neq 0
    then begin
         WORK_LEN = ch$ptr (.REQ[RB_RESPONSE], 3, 8);
         WORK_LEN = ch$plus (.WORK_LEN, ch$rchar_a (WORK_LEN));
         FMT_TABULAR_ENTITY (.HDR_ADDR[HDR_ENTITY], .WORK_LEN);
         WORK_LEN = ch$diff (.TEXT_PTR, .WORK_PTR);
         case .PRM[PRM_FORMAT] from PRM_FMT_LO to PRM_FMT_HI of
             set
             [PRM_FMT_RIGHT] :
                 LAST_PTR = ch$plus (.LINE_PTR, .PRM[PRM_COLUMN] + (.PRM[PRM_LENGTH] - .WORK_LEN));
             [PRM_FMT_CENTER] :
                 LAST_PTR = ch$plus (.LINE_PTR, .PRM[PRM_COLUMN] + (.PRM[PRM_LENGTH] - .WORK_LEN)^-1);
             [PRM_FMT_NODE] :
                 begin
                 local PTR;
                 PTR = ch$find_ch (.WORK_LEN, .WORK_PTR, %c'(');
                 if ch$fail (.PTR)
                 then LAST_PTR = .WORK_LEN + 1
                 else LAST_PTR = ch$diff (.PTR, .WORK_PTR);
                 LAST_PTR = ch$plus (.LINE_PTR, .PRM[PRM_COLUMN] +
                                     .PRM[PRM_LENGTH]^-1 - .LAST_PTR);
                 end;
             [inrange] :
                 LAST_PTR = ch$plus (.LINE_PTR, .PRM[PRM_COLUMN]);
             tes;
         LAST_PTR = ch$move (.WORK_LEN, .WORK_PTR, .LAST_PTR);
         TEXT_PTR = .WORK_PTR;
         end;
    end;

    while NEXTW_RESP 
    do begin
       DATA_ID = GETW (RESP_PTR);  ! Get the data id of this data entry

       if .DATA_ID[DI_TYPE] eql 1
       then $INTERNAL_ERROR$ ('Unexpected counter data')
       else begin                  ! Parameter field
            local PRM: ref PRM_BLOCK,
                  WORK_PTR, WORK_LEN;
            if (.DATA_ID[DI_WIDTH] neq 0) or
               (.DATA_ID[DI_MAPPED] neq 0)
            then $INTERNAL_ERROR$ ('Non-zero reserved fields in data id');

            WORK_PTR = 0;          ! Default no parameter match
            PRM = .HDR_ADDR[HDR_PARAMETER_LIST];
            decr PRM_CNT from .vector[.PRM, -1]/PRM_SIZE to 1 do
                begin              ! Find matching parameter position
                if .PRM[PRM_NUMBER] eql .DATA_ID[DI_PARMNO]
                then exitloop WORK_PTR = .TEXT_PTR; ! Found!!!
                PRM = vector [.PRM, PRM_SIZE];
                end;

            if .WORK_PTR neq 0     ! Parameter match
            then begin
                 FMT_PARAMETER (.HDR_ADDR[HDR_ENTITY], .DATA_ID, $true);
                 WORK_LEN = ch$diff (.TEXT_PTR, .WORK_PTR) - 2;
                 TEXT_PTR = .WORK_PTR;
                 WORK_PTR = ch$plus (.WORK_PTR, 2);
                 case .PRM[PRM_FORMAT] from PRM_FMT_LO to PRM_FMT_HI of
                     set
                     [PRM_FMT_RIGHT] :
                         LAST_PTR = ch$plus (.LINE_PTR, .PRM[PRM_COLUMN] + (.PRM[PRM_LENGTH] - .WORK_LEN));
                     [PRM_FMT_CENTER] :
                         LAST_PTR = ch$plus (.LINE_PTR, .PRM[PRM_COLUMN] + (.PRM[PRM_LENGTH] - .WORK_LEN)^-1);
                     [PRM_FMT_FLOAT] :
                         ch$wchar_a (%c'-', LAST_PTR);
                     [PRM_FMT_NODE] :
                         begin
                         local PTR;
                         PTR = ch$find_ch (.WORK_LEN, .WORK_PTR, %c'(');
                         if ch$fail (.PTR)
                         then LAST_PTR = .WORK_LEN + 1
                         else LAST_PTR = ch$diff (.PTR, .WORK_PTR);
                         LAST_PTR = ch$plus (.LINE_PTR, .PRM[PRM_COLUMN] +
                                         .PRM[PRM_LENGTH]^-1 - .LAST_PTR);
                         end;
                     [inrange] :
                         LAST_PTR = ch$plus (.LINE_PTR, .PRM[PRM_COLUMN]);
                     tes;
                 LAST_PTR = ch$move (.WORK_LEN, .WORK_PTR, .LAST_PTR);
                 end
            else FMT_PARAMETER (.HDR_ADDR[HDR_ENTITY], .DATA_ID, $false);
            end;	!end of else .DATA_ID[DI_TYPE]

       end;		!end of while loop

    !
    ! Terminate the text string with a null byte.
    !

    $RSP_TEXT ('%/');                   ! Terminate and set null

    return $TRUE;
    end;				! End of FMT_TABULAR_DATA
%routine ('FMT_TABULAR_ENTITY', ENTITY_TYPE, ENT_PTR) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Interpret the entity information from the response message
!       and insert the text at the current position in the text
!       buffer.
!
! FORMAL PARAMETERS
!
!	ENTITY_TYPE - The full entity type 
!       ENT_PTR     - Pointer to entity-id in response message
!
! IMPLICIT INPUTS
!
!	TEXT_PTR, TEXT_LENGTH, RESP_PTR.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	Builds response message in the usual manner
!
!--

    begin
    map 
	ENTITY_TYPE : FULL_ENTITY;

    case .ENTITY_TYPE[ENTITY_MAIN] from ENTITY_LO to ENTITY_HI of
        set
       [ENTITY_NODE] :
            begin
            local NOD_ADR;

            NOD_ADR = GETW (ENT_PTR);

            if .NOD_ADR<10,6> eql 0
            then begin
                 local TEMP;
                 TEMP = NMU$NETWORK_LOCAL();
                 TEMP = GETW (TEMP);
                 NOD_ADR<10,6> = .TEMP<10,6>;
                 end;

            $RSP_TEXT ('%M.%M%N', .NOD_ADR<10,6>, .NOD_ADR<0,10>);

            if (NOD_ADR = (GETB (ENT_PTR) and not (1^7))) neq 0
            then $RSP_TEXT (' (%#A)%N', .NOD_ADR, .ENT_PTR);

            end;
       [ENTITY_LINE, ENTITY_CIRCUIT] :
            begin
            local LEN;
            LEN = ch$rchar_a (ENT_PTR);
            $RSP_TEXT ('%#A%N', .LEN, .ENT_PTR);
            end;
       [ENTITY_AREA] :
	    if ch$rchar_a (ENT_PTR) eql 0 then
                   $RSP_TEXT ('%M%N', ch$rchar (.ENT_PTR));
       [inrange,outrange] : 0;
        tes;
    end;				! End of FMT_TABULAR_ENTITY
end                                   	! End of Module NCPRSP
eludom
! Local Modes:
! Mode:BLISS
! Auto Save Mode:1
! Comment Column:40
! Comment Rounding:+1
! End: