1  PSM_Routines
   The print symbiont modification (PSM) routines allow you to
   modify the behavior of the print symbiont supplied with the
   operating system.
 

2  PSM$PRINT
   The PSM$PRINT routine invokes the OpenVMS-supplied print
   symbiont.

   PSM$PRINT must be called exactly once after all user service
   routines have been specified using PSM$REPLACE.

   Format

     PSM$PRINT  [streams] [,bufsiz] [,worksiz] [,maxqios] [,options]
 

3  Returns
   OpenVMS usage:cond_value
   type:         longword (unsigned)
   access:       write only
   mechanism:    by value

   Longword condition value. Most utility routines return a
   condition value in R0. Condition values that this routine can
   return are listed under Condition Values Returned.
 

3  Arguments
 

streams

   OpenVMS usage:longword_unsigned
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Maximum number of streams that the symbiont is to support. The
   streams argument is the address of a longword containing this
   number, which must be in the range of 1 to 16. If you do not
   specify streams, a default value of 1 is used. Thus, by default,
   a user-modified symbiont supports one stream, which is to say
   that it is a single-threaded symbiont.

   A stream (or thread) is a logical link between a print execution
   queue and a printing device. When a symbiont process can accept
   simultaneous links to more than one queue, that is, when it can
   service multiple queues simultaneously, the symbiont is said to
   be multithreaded.
 

bufsiz

   OpenVMS usage:longword_unsigned
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Maximum buffer size in bytes that the print symbiont is to use
   for output operations. The bufsiz argument is the address of a
   longword containing the specified number of bytes.

   The print symbiont actually uses a buffer size that is the
   smaller of: (1)  the value specified by bufsiz or (2) the
   system parameter MAXBUF. If you do not specify bufsiz, the print
   symbiont uses the value of MAXBUF.

   The print symbiont uses this size limit only for output
   operations. Output operations involve the placing of processed or
   formatted pages into a buffer that will be passed to the output
   routine.

   The print symbiont uses the value specified by bufsiz only as
   an upper limit; most buffers that it writes will be smaller than
   this value.
 

worksiz

   OpenVMS usage:longword_unsigned
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Size in bytes of a work area to be allocated for the use of user
   routines. The worksiz argument is the address of a longword
   containing this size in bytes. If you do not specify worksiz,
   no work area is allocated.

   A separate area of the specified size is allocated for each
   active symbiont stream.
 

maxqios

   OpenVMS usage:longword_unsigned
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference

   Specifies the maximum number of outstanding $QIOs that a print
   symbiont stream using the LAT protocol may generate. Set symbiont
   process quotas large enough to handle the maximum number of QIOs
   multiplied by the number of streams, using a number between 2 and
   32. For normal printing capabilities, the suggested quota is 10;
   for high-speed printing, use a larger number.
 

options

   OpenVMS usage:longword_unsigned
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference

   Longword bit vector that specifies the LAT protocal option using
   the PSM$M_LAT_PROTOCOL symbolic value. Note that using the LAT_
   PROTOCOL option carries the following restrictions:

   o  Replacement of the output and job completion routines will be
      overridden

   o  Output device must be a LAT device
 

3  Description
   The PSM$PRINT routine must be called exactly once after all user
   routines have been specified to the print symbiont. Each user
   routine is specified to the symbiont in a call to the PSM$REPLACE
   routine.

   The PSM$PRINT routine allows you to specify whether the print
   symbiont is to be single-threaded or multithreaded, and if
   multithreaded, how many streams or threads it can have. In
   addition, this routine allows you to control the maximum size
   of the output buffer.
 

3  Condition_Values_Returned

   SS$_NORMAL         Normal successful completion.

   This routine also returns any condition values returned by the
   $SETPRV, $GETSYI, $PURGWS, and $DCLAST system services, as well
   as any condition values returned by the SMB$INITIALIZE routine.
 

2  PSM$READ_ITEM_DX
   The PSM$READ_ITEM_DX routine obtains the value of message items
   that are sent by the job controller and stored by the symbiont.

   Format

     PSM$READ_ITEM_DX  request_id ,item ,buffer
 

3  Returns
   OpenVMS usage:cond_value
   type:         longword (unsigned)
   access:       write only
   mechanism:    by value

   Longword condition value. Most utility routines return a
   condition value in R0. Condition values that this routine can
   return are listed under Condition Values Returned.
 

3  Arguments
 

request_id

   OpenVMS usage:address
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Request identifier supplied by the symbiont to the user routine
   currently calling PSM$READ_ITEM_DX. The symbiont always supplies
   a request identifier when it calls a user routine with a service
   request. The request_id argument is the address of a longword
   containing this request identifier value.

   Your user routine must copy the request identifier value that the
   symbiont supplies (in the request_id argument) when it calls your
   user routine. Then, when your user routine calls PSM$READ_ITEM_
   DX, it must supply (in the request_id argument) the address of
   the request identifier value that it copied.
 

item

   OpenVMS usage:longword_unsigned
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Item code that identifies the message item that PSM$READ_ITEM_DX
   is to return. The item argument is the address of a longword that
   specifies the item's code.
 

buffer

   OpenVMS usage:char_string
   type:         character string
   access:       write only
   mechanism:    by descriptor
   Buffer into which PSM$READ_ITEM_DX returns the specified
   informational item. The buffer argument is the address of a
   descriptor pointing to this buffer.

   The PSM$READ_ITEM_DX routine returns the specified informational
   item by copying that item to the buffer using one of the
   STR$COPY_xx routines documented in the OpenVMS RTL String
   Manipulation (STR$) Manual.
 

3  Description
   The PSM$READ_ITEM_DX routine obtains the value of message items
   that are sent by the job controller and stored by the symbiont.
   Use PSM$READ_ITEM_DX to obtain information about the task
   currently being processed, for example, the name of the file
   being printed (SMBMSG$K_FILE_SPECIFICATION) or the name of the
   user who submitted the job (SMBMSG$K_USER_NAME).
 

3  Condition_Values_Returned

   SS$_NORMAL         Normal successful completion.
   PSM$_INVITMCOD     Invalid item code specified in the item
                      argument.

   This routine also returns any condition values returned by any
   of the STR$COPY_xx routines documented in the OpenVMS RTL String
   Manipulation (STR$) Manual.
 

2  PSM$REPLACE
   The PSM$REPLACE routine substitutes a user service routine for
   a symbiont routine or adds a user service routine to the set of
   symbiont routines.

   You must call PSM$REPLACE once for each routine that you replace
   or add.

   Format

     PSM$REPLACE  code ,routine
 

3  Returns
   OpenVMS usage:cond_value
   type:         longword (unsigned)
   access:       write only
   mechanism:    by value

   Longword condition value. Most utility routines return a
   condition value in R0. The condition value that this routine
   can return is listed under Condition Value Returned.
 

3  Arguments
 

code

   OpenVMS usage:longword_unsigned
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Routine code that identifies the symbiont routine to be replaced
   by a user service routine. The code argument is the address of a
   longword containing the routine code.

   Some routine codes identify routines that are supplied with the
   symbiont; when you specify such a routine code, you replace the
   symbiont-supplied routine with your service routine.

   Two routine codes identify routines that are not supplied with
   the symbiont; when you specify such a routine code, your service
   routine is added to the set of symbiont routines.


   Each programming language provides an appropriate mechanism for
   defining these routine codes. The following pages list each
   routine code in alphabetical order; the description of each
   code includes the following information about its corresponding
   routine:

   o  Whether the routine is supplied by the symbiont

   o  Whether the routine is an input, formatting, or output routine

   o  Under what conditions the routine is called

   o  What task the routine performs
 

3  Routine_Codes
 

PSM$K_FILE_BURST

   This code identifies a symbiont-supplied input routine; it is
   called whenever a file burst page is requested. This routine
   obtains information about the job, formats the file burst page,
   and returns the contents of the page to the input buffer. A file
   burst page follows a file flag page and precedes the contents of
   the file.
 

PSM$K_FILE_ERRORS

   This code identifies a symbiont-supplied input routine; it is
   called when errors have occurred during the job. This routine
   places the error message text in the input buffer.
 

PSM$K_FILE_FLAG

   This code identifies a symbiont-supplied input routine; it is
   called whenever a file flag page is requested. This routine
   obtains information about the job, formats the file flag page,
   and returns the contents of the page to the input buffer. A flag
   page follows the job burst page (if any) and precedes the file
   burst page (if any). It contains such information as the file
   specification of the file and the name of the user issuing the
   print request.
 

PSM$K_FILE_INFORMATION

   This code identifies a symbiont-supplied input routine; it is
   called when the file information item has been specified by the
   job controller. This routine expands the file information item to
   text and returns it to the input buffer.
 

PSM$K_FILE_SETUP

   This code identifies a symbiont-supplied input routine; it is
   always called. This routine queues any specified file-setup
   modules for insertion in the input stream when the PSM$K_FILE_
   SETUP routine closes.
 

PSM$K_FILE_SETUP_2

   This code identifies a symbiont-supplied input routine; it is
   always called. This routine returns a form feed to ensure that
   printing of the file begins at the top of the page. This routine
   is called just before the main input routine.
 

PSM$K_FILE_TRAILER

   This code identifies a symbiont-supplied input routine; it is
   called whenever a file trailer page is requested. This routine
   obtains information about the job, formats the file trailer
   page, and returns the contents of the page to the input buffer. A
   trailer page follows the last page of the file contents.
 

PSM$K_MAIN_FORMAT

   This code identifies the symbiont-supplied formatting routine;
   it is always called. This routine performs numerous formatting
   functions. You cannot replace this routine.
 

PSM$K_FORM_SETUP

   This code identifies a symbiont-supplied input routine; it is
   always called. This routine queues any specified form-setup
   modules for insertion in the input stream when the PSM$K_FORM_
   SETUP routine closes.
 

PSM$K_INPUT_FILTER

   This code identifies a format routine that is not supplied by the
   symbiont. If the routine is supplied by the user, it is always
   called immediately prior to the symbiont-supplied formatting
   routine (routine code PSM$K_MAIN_FORMAT). An input-filter service
   routine is useful for modifying input data records and their
   carriage control before they are formatted by the symbiont.
 

PSM$K_JOB_BURST

   This code identifies a symbiont-supplied input routine; it is
   called whenever a job burst page is requested. This routine
   obtains information about the job, formats the job burst page,
   and returns the contents of the page to the input buffer. A job
   burst page follows the job flag page and precedes the file flag
   page (if any) of the first file in the job. It is similar to a
   file burst page except that it appears only once per job and only
   at the beginning of the job.
 

PSM$K_JOB_COMPLETION

   This code identifies a symbiont-supplied input routine that
   returns a form feed, which causes any output stored by the
   device to be printed. The routine is always called. It cannot
   be replaced when using the LAT protocol option.
 

PSM$K_JOB_FLAG

   This code identifies a symbiont-supplied input routine; it is
   called whenever a job flag page is requested. This routine
   obtains information about the job, formats the job flag page,
   and returns the contents of the page to the input buffer. A job
   flag page is similar to a file flag page except that it appears
   only once per job, preceding the job burst page (if any).
 

PSM$K_JOB_RESET

   This code identifies a symbiont-supplied input routine; it is
   always called. This routine queues any specified job-reset
   modules for insertion in the input stream when the PSM$K_JOB_
   RESET routine closes.
 

PSM$K_JOB_SETUP

   This code identifies a symbiont-supplied input routine; it is
   always called. This routine checks to see if this is the first
   job to be printed on the device, and if so, it issues a form feed
   and then performs a job reset. See the description of the PSM$K_
   JOB_RESET routine for information about job reset.
 

PSM$K_JOB_TRAILER

   This code identifies a symbiont-supplied input routine; it is
   called whenever a job trailer page is requested. This routine
   obtains information about the job, formats the job trailer page,
   and returns the contents of the page to the input buffer. A job
   trailer page is similar to a file trailer page except that it
   appears only once per job, as the last page in the job.
 

PSM$K_MAIN_INPUT

   This code identifies a symbiont-supplied input routine; it is
   always called. This routine opens the file to be printed, returns
   input records to the input buffer, and closes the file.
 

PSM$K_LIBRARY_INPUT

   This code identifies a symbiont-supplied input routine; it is
   called when an input routine closes and when modules have been
   requested for insertion in the input stream. This routine returns
   the contents of the specified modules, one record per call. You
   cannot replace this routine.
 

PSM$K_OUTPUT_FILTER

   This code identifies a formatting routine that is not supplied
   by the symbiont. If the routine is supplied by the user, it is
   always called. This routine executes prior to the symbiont output
   routine (routine code PSM$K_OUTPUT). An output-filter service
   routine is useful for modifying output data buffers before they
   are passed to the output routine.

   At the point where the output-filter routine executes within the
   symbiont execution stream, the input data is no longer in record
   format; instead, the data exists as a stream of characters. The
   carriage control, for example, is embedded in the data stream.
   Thus, the output buffer might contain what was once a complete
   record, part of a record, or several records.
 

PSM$K_PAGE_HEADER

   This code identifies a symbiont-supplied input routine; it is
   called once at the beginning of each page if page headers are
   requested. This routine returns to the input buffer one or more
   lines containing information about the file being printed and the
   current page number. This routine is called only while the main
   input routine is open.
 

PSM$K_PAGE_SETUP

   This code identifies a symbiont-supplied routine; it is called at
   the beginning of each page if page-setup modules were specified.
   This routine queues any specified page-setup modules for
   insertion in the input stream when the PSM$K_PAGE_SETUP routine
   closes. This routine is called only while the main input routine
   is open.
 

PSM$K_OUTPUT

   This code identifies the symbiont-supplied output routine that
   writes the contents of the output buffer to the printing device,
   together with many other functions. This routine is always
   called. It cannot be replaced when using the LAT protocol option.
 

routine

   OpenVMS usage:procedure
   type:         procedure value
   access:       read only
   mechanism:    by reference
   User service routine that is to replace a symbiont routine or
   to be included. The routine argument is the address of the user
   routine entry point.
 

3  Description
   The PSM$REPLACE routine must be called each time a user service
   routine replaces a symbiont routine or is added to a set of
   symbiont routines.

   The code argument specifies the symbiont routine to be replaced.
   The routine codes that can be specified in the code argument
   are of two types: those that identify existing print symbiont
   routines and those that do not. All the routine codes are
   similar, however, in the sense that each supplies a location
   within the print symbiont execution stream where your routine can
   execute.

   By selecting a routine code that identifies an existing symbiont
   routine, you effectively disable that symbiont routine. The
   service routine that you specify might or might not perform
   the function that the disabled symbiont routine performs. If
   it does not, the net effect of the replacement is to eliminate
   that function from the list of functions performed by the print
   symbiont. Exactly what your service routine does is up to you.

   By selecting a routine code that does not identify an existing
   symbiont routine (those that identify the input-filter and
   output-filter routines), your service routine has a chance to
   execute at the location signified by the routine code. Because
   the service routine you specify to execute at this location does
   not replace another symbiont routine, your service routine is an
   addition to the set of symbiont routines.

   As mentioned, each routine code identifies a location in the
   symbiont execution stream, whether or not it identifies a
   symbiont routine.
 

3  Condition_Value_Returned

   SS$_NORMAL         Normal successful completion.
 

2  PSM$REPORT
   The PSM$REPORT routine reports to the print symbiont the
   completion status of an asynchronous operation initiated by a
   user routine.

   Such a user routine must return the completion status PSM$_
   PENDING. PSM$REPORT must be called exactly once for each time
   a user routine returns the status PSM$_PENDING.

   Format

     PSM$REPORT  request_id [,status]
 

3  Returns
   OpenVMS usage:cond_value
   type:         longword (unsigned)
   access:       write only
   mechanism:    by value

   Longword condition value. Most utility routines return a
   condition value in R0. The condition value that this routine
   can return is listed under Condition Value Returned.
 

3  Arguments
 

request_id

   OpenVMS usage:address
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Request identifier supplied by the symbiont to the user routine
   at the time the symbiont called the user routine with the service
   request. The user routine must return the completion status PSM$_
   PENDING on the call for this service request. The request_id
   argument is the address of a longword containing the request
   identifier value.

   The symbiont calls the user routine with a request code that
   specifies the function that the symbiont expects the user
   routine to perform. In the call, the symbiont also supplies a
   request identifier, which serves to identify the request. If the
   user routine initiates an asynchronous operation, a mechanism
   is required for notifying the symbiont that the asynchronous
   operation has completed and for providing the completion status
   of the operation.

   The PSM$REPORT routine conveys the above two pieces of
   information. In addition, PSM$REPORT returns to the symbiont
   (in the request_id argument) the same request identifier value
   as that supplied by the symbiont to the user routine that
   initiated the operation. In this way, the symbiont synchronizes
   the completion status of an asynchronous operation with that
   invocation of the user routine that initiated the operation.

   Any user routine that initiates an asynchronous operation must,
   therefore, copy the request identifier value that the symbiont
   supplies (in the request_id argument) when it calls the user
   routine. The user routine will later need to supply this value to
   PSM$REPORT.

   In addition, when the user routine returns, which it does before
   the asynchronous operation has completed, the user routine must
   return the status PSM$_PENDING.
 

status

   OpenVMS usage:cond_value
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Completion status of the asynchronous operation that has
   completed. The status argument is the address of a longword
   containing this completion status. The status argument is
   optional; if it is not specified, the symbiont assumes the
   completion status SS$_NORMAL.

   The user routine that initiates the asynchronous operation
   must test for the completion of the operation and must supply
   the operation's completion status as the status argument to
   the PSM$REPORT routine. The Description section describes this
   procedure in greater detail.

   If the completion status specified by status has the low bit
   clear, the symbiont aborts the task.
 

3  Description
   An asynchronous operation is an operation that, once initiated,
   executes "off to the side" and need not be completed before other
   operations can begin to execute. Asynchronous operations are
   common in symbiont applications because a symbiont, if it is
   multithreaded, must handle concurrent I/O operations.

   One example of a user routine that performs an asynchronous
   operation is an output routine that calls the $QIO system service
   to write a record to the printing device. When the user output
   routine completes execution, the I/O request queued by $QIO might
   not have completed. In order to synchronize this I/O request,
   that is, to associate the I/O request with the service request
   that initiated it, you should use the following mechanism:

   1. In making the call to $QIO, specify the astadr and iosb
      arguments. The astadr argument specifies an AST routine to
      execute when the queued output request has completed, and the
      iosb argument specifies an I/O status block to receive the
      completion status of the I/O operation. Step 3 describes some
      functions that your AST routine will need to do.

   2. Have the user output routine return the status PSM$_PENDING.

   3. Write the AST routine to perform the following functions:

      a. Copy the completion status word from the I/O status block
         to a longword location that you will specify as the status
         argument in the call to PSM$REPORT.

      b. Call PSM$REPORT. Specify as the request_id argument the
         request identifier that was supplied by the print symbiont
         in the original call to the user output routine.
 

3  Condition_Value_Returned

   SS$_NORMAL         Normal successful completion.
 

2  USER-FORMAT-ROUTINE
   The user-written USER-FORMAT-ROUTINE performs format operations.
   The symbiont's control logic routine calls your format routine
   at one of two possible points within the symbiont's execution
   stream. You select this point by specifying one of two routine
   codes when you call the PSM$REPLACE routine.

   A user format routine can be an input filter routine (routine
   code PSM$K_INPUT_FILTER) or an output filter routine (routine
   code PSM$K_OUTPUT_FILTER). The main format routine (routine code
   PSM$K_MAIN_FORMAT) cannot be replaced.

   A user format routine must use the call interface described here.

   Format

     USER-FORMAT-ROUTINE  request_id ,work_area ,func ,func_desc_1

                          ,func_arg_1 ,func_desc_2 ,func_arg_2
 

3  Returns
   OpenVMS usage:cond_value
   type:         longword (unsigned)
   access:       write only
   mechanism:    by value

   Longword condition value. Most utility routines return a
   condition value in R0. Condition values that this routine can
   return are listed under Condition Values Returned.
 

3  Arguments
 

request_id

   OpenVMS usage:address
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Request identifier supplied by the symbiont when it calls your
   format routine. The request_id argument is the address of a
   longword containing this request identifier value.
 

work_area

   OpenVMS usage:address
   type:         longword (unsigned)
   access:       write only
   mechanism:    by reference
   Work area supplied by the symbiont for the use of your format
   routine. The symbiont supplies the address of this area when
   it calls your routine. The work_area argument is a longword
   containing the address of the work area. The work area is a
   section of memory that your format routine can use for buffering
   and other internal operations.

   The size of the work area allocated is specified by the work_size
   argument in the PSM$PRINT routine. If you do not specify work_
   size in the call to PSM$PRINT, no work area is allocated.

   In a multithreaded symbiont, a separate work area is allocated
   for each thread. This work area is shared by all user routines.
   The work area is initialized to zero when the symbiont is first
   started.
 

func

   OpenVMS usage:function_code
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Function code specifying the service that the symbiont expects
   your format routine to perform. The func argument is the address
   of a longword into which the symbiont writes this function code.

   The function code specifies the reason the symbiont is calling
   your format routine or, in other words, the service that the
   symbiont expects your routine to perform at this time.

   The PSM$K_FORMAT function code is the only one to which your
   format routine must respond. When the symbiont calls your format
   routine with this function code, your routine must move a record
   from the input buffer to the output buffer.

   The symbiont can call your format routine with other function
   codes. Your routine should return the status PSM$_FUNNOTSUP
   (function not supported) when it is called with any of the
   following function codes or with any undocumented function code.
   When the status PSM$_FUNNOTSUP is returned, the symbiont performs
   its normal action as if no format routine were supplied. To
   suppress the symbiont's normal action, you should return SS$_
   NORMAL.

   PSM$K_START_STREAM     PSM$K_STOP_STREAM
   PSM$K_START_TASK       PSM$K_PAUSE_TASK
   PSM$K_RESUME_TASK      PSM$K_STOP_TASK
   PSM$K_RESET_STREAM

   These function codes correspond to message items sent by the job
   controller to the symbiont.

   Other function codes correspond to internal symbiont mechanisms
   that are not part of the public interface to the print symbiont.

   Your format routine should return the status PSM$_FUNNOTSUP or
   SS$_NORMAL when it is called with a message function code or with
   a private function code.
 

func_desc_1

   OpenVMS usage:char_string
   type:         character string
   access:       read only
   mechanism:    by descriptor
   Descriptor supplying an input record to be processed by the
   format routine. The func_desc_1 argument is the address of a
   string descriptor. By using this argument, the symbiont supplies
   the input record that your format routine is to process. Because
   this descriptor can be of any valid string type, your format
   routine should use the Run-Time Library string routines to
   analyze this descriptor and to manipulate the input record.
 

func_arg_1

   OpenVMS usage:vector_byte_unsigned
   type:         byte (unsigned)
   access:       read only
   mechanism:    by reference
   Carriage control for the input record supplied by func_desc_
   1. The func_arg_1 argument is the address of a 4-byte vector
   that specifies the carriage control for the input record. The
   following diagram depicts the format of this 4-byte vector:







   Bytes 0 and 1 describe the leading carriage control to apply
   to the input data record; bytes 2 and 3 describe the trailing
   carriage control.

   Byte 0 is a number specifying the number of times the carriage
   control specifier in byte 1 is to be repeated preceding the
   input data record. Byte 2 is a number specifying the number of
   times the carriage control specifier in byte 3 is to be repeated
   following the input data record.

   For values of the carriage control specifier from 1 to 255, the
   specifier is the ASCII character to be used as carriage control.
   Value 0 represents the ASCII "newline" sequence. Newline consists
   of a carriage return followed by a linefeed.

   The func_arg_1 argument is not used if your format routine is an
   output filter routine (routine code PSM$K_OUTPUT_FILTER). See the
   Description section for more information.
 

func_desc_2

   OpenVMS usage:char_string
   type:         character string
   access:       write only
   mechanism:    by reference
   Descriptor of a buffer to which your format routine writes the
   formatted output record. The func_desc_2 argument is the address
   of a string descriptor.

   Your format routine must return the formatted data record by
   using the func_desc_2 argument.

   Your format routine should use the Run-Time Library string
   routines to write into the buffer specified by this descriptor.
 

func_arg_2

   OpenVMS usage:vector_byte_unsigned
   type:         byte (unsigned)
   access:       write only
   mechanism:    by reference
   Carriage control for the output record returned in func_desc_2.
   The func_arg_2 argument is the address of a 4-byte vector that
   specifies the carriage control for the output record. See the
   description of func_arg_1 for the contents and format of this
   4-byte vector.

   If you do not process the carriage-control information supplied
   in func_arg_1, then you should copy that value into func_arg_2.
   Otherwise, the carriage-control information will be lost.

   The func_arg_2 argument is not used if your format routine is an
   output filter routine (routine code PSM$K_OUTPUT_FILTER). See the
   Description section for more information.
 

3  Description
   When used, the func_arg_1 argument describes carriage-control
   information for the input data record, and the func_arg_2
   argument describes carriage-control information for the output
   data record.

   The input data record is passed to the format routine (input
   filter or output filter) for processing, and the output data
   record is returned by the format routine (input filter or output
   filter).

   One of the tasks performed by the main format routine (routine
   code PSM$K_MAIN_FORMAT) is that of embedding the carriage-control
   information (specified by func_arg_1) into the data record
   (specified by func_desc_1). Thus, the output data (specified
   by func_desc_2) contains embedded carriage control and is thus no
   longer in record format; it is, therefore, properly referred to
   as an output data stream rather than an output data record.

   Similarly, the output filter routine (routine code PSM$K_OUTPUT_
   FILTER), which executes after the main format routine, uses
   neither the func_arg_1 nor func_arg_2 argument; the data it
   receives (via func_desc_1) and the data it returns (via func_
   desc_2) are data streams, not data records.

   However, the input filter routine (routine code PSM$K_INPUT_
   FILTER), which executes before the main format routine, uses
   both func_arg_1 and func_arg_2. This is so because the main
   format routine has not yet executed, and so the carriage control
   information has not yet been embedded in the data record.
 

3  Condition_Values_Returned

   SS$_NORMAL         Successful completion. The user format routine
                      has completed the function that the symbiont
                      requested.
   PSM$_FUNNOTSUP     Function not supported. The user format
                      routine does not support or does not recognize
                      the function code supplied by the symbiont.
                      To ensure future compatibility, your format
                      routine should return this status for any
                      unrecognized status codes.

   This routine also returns any error condition values that you
   have coded your format routine to return.
 

2  USER-INPUT-ROUTINE
   The user-written USER-INPUT-ROUTINE performs input operations.
   The symbiont calls your routine at a specified point in its
   execution stream; you specify this point using the PSM$REPLACE
   routine.

   Format

     USER-INPUT-ROUTINE  request_id ,work_area ,func ,funcdesc

                         ,funcarg
 

3  Returns
   OpenVMS usage:cond_value
   type:         longword (unsigned)
   access:       write only
   mechanism:    by value

   Longword condition value. Most utility routines return a
   condition value in R0. Condition values that this routine can
   return are listed under Condition Values Returned.
 

3  Arguments
 

request_id

   OpenVMS usage:address
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Request identifier value supplied by the symbiont when it calls
   your input routine. The request_id argument is the address of a
   longword containing this request identifier value.

   If your input routine initiates an asynchronous operation (for
   example, a call to the $QIO system service), your input routine
   must copy the request identifier value specified by request_
   id because this value must later be passed to the PSM$REPORT
   routine. See the description of the PSM$REPORT routine for more
   information.
 

work_area

   OpenVMS usage:address
   type:         longword (unsigned)
   access:       write only
   mechanism:    by reference
   Work area supplied by the symbiont for the use of your input
   routine. The symbiont supplies the address of this area when it
   calls your routine. The work_area argument is a longword into
   which the symbiont writes the address of the work area. The work
   area is a section of memory that your input routine can use for
   buffering and for other internal operations.

   The size of the work area allocated is specified by the work_size
   argument in the PSM$PRINT routine. If you do not specify work_
   size in the call to PSM$PRINT, no work area is allocated.

   In a multithreaded symbiont, a separate work area is allocated
   for each thread. This work area is shared by all user routines.
   The work area is initialized to zero when the symbiont is first
   started.
 

func

   OpenVMS usage:function_code
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Function code supplied by the symbiont when it calls your
   input routine. The func argument is the address of a longword
   containing this code.

   The function code specifies the reason the symbiont is calling
   your input routine or, in other words, the function that the
   symbiont expects your routine to perform at this time.

   Most function codes require or allow additional information
   to be passed in the call by means of the funcdesc and funcarg
   arguments. The description of each input function code,
   therefore, includes a description of how these two arguments
   are used with that function code.

   Following is a list of all the function codes that the symbiont
   can specify when it calls your input routine (function codes
   applicable only to format and output routines are explained in
   the descriptions of the USER-FORMAT-ROUTINE and USER-OUTPUT-
   ROUTINE, respectively); all function codes are defined by the
   $PSMDEF macro.
 

3  Function_Codes_for_Input_Routines
 

PSM$K_CLOSE

   When the symbiont calls your routine with this function code,
   your routine must terminate processing by releasing any resources
   it might have allocated.

   The symbiont calls your routine with PSM$K_CLOSE when (1)  your
   routine returns from a PSM$K_READ function call with the status
   PSM$_EOF (end of input) or with any error condition, or (2)
   the symbiont receives a task-abortion request from the job
   controller.

   In any event, the symbiont always calls your input routine
   with PSM$K_CLOSE if your routine returns successfully from a
   PSM$K_OPEN function call. This guaranteed behavior ensures that
   any resources your routine might have allocated on the OPEN will
   be released on the CLOSE.
 

PSM$K_GET_KEY

   Typically, the use of both the PSM$K_GET_KEY and PSMK$K_POSITION_
   TO_KEY function codes is appropriate only for a main input
   routine (routine code PSM$K_MAIN_INPUT).

   When the symbiont calls your routine with this function code,
   your routine can do one of two things: (1)  return PSM$_FUNNOTSUP
   (function not supported) or (2)  return an input marker string to
   the symbiont.

   If your routine returns PSM$_FUNNOTSUP to this function code,
   then your routine must also return PSM$_FUNNOTSUP if the symbiont
   subsequently calls your routine with the PSM$K_POSITION_TO_KEY
   function code. By returning PSM$_FUNNOTSUP, your routine is
   choosing not to respond to the symbiont request.

   If your routine chooses to respond to the PSM$K_GET_KEY function
   code, your routine must return an input marker string to the
   symbiont; this input marker string identifies the input record
   that your input routine most recently returned to the symbiont.
   Subsequently, when the symbiont calls your input routine with
   the PSM$K_POSITION_TO_KEY function code, the symbiont passes your
   input routine one of the input marker strings that your input
   routine has returned on a previous PSM$K_GET_KEY function call.
   Using this marker string, your input routine must position itself
   so that, on the next PSM$K_READ call from the symbiont, your
   input routine will return (or reread) the input record identified
   by the marker string.

   Coding your input routine to respond to PSM$K_GET_KEY and
   PSM$K_POSITION_TO_KEY allows the modified symbiont to perform
   the file-positioning functions specified by the DCL commands
   START/QUEUE/FORWARD, START/QUEUE/ALIGN, START/QUEUE/TOP_OF_
   FILE, START/QUEUE/SEARCH, and START/QUEUE/BACKWARD. These
   file positioning functions also depend on the job controller's
   checkpointing capability for print jobs.

   Note that your input routine might be called with a marker string
   that was originally returned in a different process context
   from the current one. This can occur because marker strings are
   sometimes stored in the queue-data file across system shutdowns
   or different invocations of your symbiont.

   The funcdesc argument specifies the address of a string
   descriptor. Your routine must return the marker string by way
   of this argument. Compaq recommends that you use one of the Run-
   Time Library string routines to copy the marker string to the
   descriptor.

   The symbiont periodically calls your input routine with the
   PSM$K_GET_KEY function code when the symbiont wants to save a
   marker to a particular input record.
 

PSM$K_OPEN

   When the symbiont calls your routine with this function code,
   your routine should prepare for input operations by performing
   such tasks as allocating necessary resources, initializing
   storage areas, opening an input file, and so on. Typically, the
   next time the symbiont calls your input routine, the symbiont
   will specify the PSM$K_READ function code. Note, however, that
   under some circumstances the symbiont might follow an OPEN call
   immediately with a CLOSE call.

   The funcdesc argument points to the name of the file to be
   opened. Your routine can use this file specification or the file
   identification to open the file.

   The funcarg argument specifies the address of a longword. Your
   input routine must return, in this longword, the carriage control
   type that is to be applied to the input records that your input
   routine will provide.

   The symbiont formatting routine requires this information to
   determine where to apply leading and trailing carriage control
   characters to the input records that your input routine will
   provide.
 

   The $PSMDEF macro defines the following four carriage control
   types:

   Carriage
   Control Type     Description

   PSM$K_CC_        Implied carriage control. For this type, the
   IMPLIED          symbiont inserts a leading line feed (LF)  and
                    trailing carriage return (CR)  in each input
                    record. This is the default carriage control
                    type; it is used if your routine does not supply
                    a carriage control type in the funcarg argument
                    in response to the PSM$K_OPEN function call.
   PSM$K_CC_        Fortran carriage control. For this type, the
   FORTRAN          symbiont extracts the first byte of each input
                    record and interprets the byte as a Fortran
                    carriage control character, which it then
                    applies to the input record.
   PSM$K_CC_PRINT   PRN carriage control. For this type, the
                    symbiont generates carriage control from a
                    2-byte record header that your input routine
                    supplies, with each READ call, in the funcarg
                    argument. The funcarg argument specifies the
                    address of a longword to receive this 2-byte
                    header record, which appears only in PRN print
                    files.
   PSM$K_CC_        Embedded carriage control. For this type, the
   INTERNAL         symbiont supplies no carriage control to input
                    records. Carriage control is assumed to be
                    embedded in the input records.
 

PSM$K_POSITION_TO_KEY

   When the symbiont calls your routine with this function code,
   your routine must locate the point in the input stream designated
   by the marker string that your routine returned to the symbiont
   on the PSM$K_GET_KEY function call.

   The next time the symbiont calls your routine, the symbiont
   specifies the PSM$K_READ function call, expecting to receive
   the next sequential input record. After rereading this record,
   subsequent READ calls proceed from this new position of the
   file. This is not a one-time rereading of a single record but
   a repositioning of the file. The symbiont calls your routine with
   this function code when the job controller receives a request to
   resume printing at a particular page.

   Refer to the description of the PSM$K_GET_KEY for more
   information.
 

PSM$K_READ

   When the symbiont calls your routine with this function code,
   your routine must return an input record. The symbiont repeatedly
   calls your input routine with the PSM$K_READ function code
   until: (1)  your routine indicates end of input by returning
   the status PSM$_EOF, (2)  your routine or another routine returns
   an error status, or (3)  the symbiont receives an asynchronous
   task-abortion request from the job controller.

   The funcdesc argument specifies the address of a string
   descriptor. Your routine must return the input record by using
   this argument. Compaq recommends that you use one of the Run-
   Time Library string routines to copy the input record to the
   descriptor.

   The funcarg argument specifies the address of a longword. This
   argument is used only if the carriage control type returned by
   your input routine on the PSM$K_OPEN function call was PSM$K_
   CC_PRINT. In this case, your input routine must supply, in the
   funcarg argument, the 2-byte record header found at the beginning
   of each input record.
 

PSM$K_REWIND

   When the symbiont calls your routine with this function code,
   your routine must do one of two things: (1)  return PSM$_
   FUNNOTSUP (function not supported) or (2)  locate the point in
   the input stream designated as the beginning of the file.

   If your routine returns PSM$_FUNNOTSUP to this function code,
   then the symbiont subsequently calls your input routine with
   a PSM$K_CLOSE function call followed by a PSM$K_OPEN function
   call. By returning PSM$_FUNNOTSUP, your routine is choosing
   not to support the repositioning of the input service to the
   beginning of the file. The symbiont, therefore, performs the
   desired function by closing and then reopening the input routine.

   You cannot use the funcdesc and the funcarg arguments with this
   function code.

   This function call allows the modified symbiont to perform
   the file-positioning functions specified by the DCL
   commands START/QUEUE/TOP_OF_FILE, START/QUEUE/FORWARD,
   START/QUEUE/BACKWARD, START/QUEUE/SEARCH, and START/QUEUE/ALIGN.
   This is a required repositioning of the file.
 

Other Input Function Codes

   The symbiont can call your input routine with other function
   codes. Your routine must return the status PSM$_FUNNOTSUP
   (function not supported) when it is called with any of the
   following function codes or with any undocumented function
   code. When the status PSM$_FUNNOTSUP is returned, the symbiont
   performs its normal action as if no input routine were supplied.
   To suppress the symbiont's normal action, you should return SS$_
   NORMAL.

   PSM$K_START_STREAM     PSM$K_STOP_STREAM
   PSM$K_START_TASK       PSM$K_PAUSE_TASK
   PSM$K_RESUME_TASK      PSM$K_STOP_TASK
   PSM$K_RESET_STREAM

   These function codes correspond to message items sent by the job
   controller to the symbiont.

   Other function codes correspond to internal symbiont mechanisms
   that are not part of the public interface to the print symbiont.

   Your input routine should return the status PSM$_FUNNOTSUP or
   SS$_NORMAL when it is called with a message function code or with
   a private function code.
 

funcdesc

   OpenVMS usage:char_string
   type:         character string
   access:       read only
   mechanism:    by descriptor
   Function descriptor supplying information related to the function
   specified by the func argument. The funcdesc argument is the
   address of this descriptor.

   The contents of the function descriptor can vary for each
   function. Refer to the description of each function code to
   determine the contents of the function descriptor. In some cases,
   the function descriptor is not used at all.
 

funcarg

   OpenVMS usage:longword_unsigned
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Function argument supplying information related to the function
   specified by the func argument. The funcarg argument is the
   address of a longword containing this function argument. This
   argument can be an input or an output argument, depending on the
   function request, but is usually used as an output argument.
 

3  Condition_Values_Returned

   SS$_NORMAL         Successful completion. The user input routine
                      has completed the function that the symbiont
                      requested.
   PSM$_FLUSH         Flush output stream. The user input routine
                      can return this status only when called with
                      the PSM$K_READ function code. When this status
                      is returned to the symbiont, the symbiont
                      stops calling the input routine with the
                      PSM$K_READ function code until all outstanding
                      format and output operations have completed.
   PSM$_FUNNOTSUP     Function not supported. The user input routine
                      does not support or does not recognize the
                      function code supplied by the symbiont.
                      To ensure future compatibility, your input
                      routine should return this status for any
                      unrecognized status codes.
   PSM$_PENDING       Requested function accepted but not completed.
                      Your input routine can return this status only
                      with the PSM$K_READ function call. Further,
                      if your routine returns PSM$_PENDING, your
                      routine must eventually signal completion
                      via the PSM$REPORT routine. Refer to the
                      description of the PSM$REPORT routine for
                      more information about asynchronous operations
                      and the PSM$_PENDING condition value.

   This routine also returns any error condition values that you
   have coded your format routine to return.
 

2  USER-OUTPUT-ROUTINE
   The user-written USER-OUTPUT-ROUTINE performs output operations.
   You supply a user output routine by calling the PSM$REPLACE
   routine with the routine code PSM$K_OUTPUT.

   Format

     USER-OUTPUT-ROUTINE  request_id ,work_area ,func ,funcdesc

                          ,funcarg
 

3  Returns
   OpenVMS usage:cond_value
   type:         longword (unsigned)
   access:       write only
   mechanism:    by value

   Longword condition value. Most utility routines return a
   condition value in R0. Condition values that this routine can
   return are listed under Condition Values Returned.
 

3  Arguments
 

request_id

   OpenVMS usage:address
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Request identifier value supplied by the symbiont when it calls
   your output routine. The request_id argument is the address of a
   longword containing this value.

   If your output routine initiates an asynchronous operation (for
   example, a call to the $QIO system service), you must save the
   request_id argument because you will need to store the request
   identifier value for later use with the PSM$REPORT routine. See
   the description of the PSM$REPORT routine for more information.
 

work_area

   OpenVMS usage:address
   type:         longword (unsigned)
   access:       write only
   mechanism:    by reference
   Work area supplied by the symbiont for the use of your format
   routine. The symbiont supplies the address of this area when
   it calls your routine. The work_area argument is a longword
   containing the address of the work area. The work area is a
   section of memory that your format routine can use for buffering
   and other internal operations.

   The size of the work area allocated is specified by the work_size
   argument in the PSM$PRINT routine. If you do not specify work_
   size in the call to PSM$PRINT, no work area is allocated.

   In a multithreaded symbiont, a separate work area is allocated
   for each thread. This work area is shared by all user routines.
   The work area is initialized to zero when the symbiont is first
   started.
 

func

   OpenVMS usage:function_code
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Function code supplied by the symbiont when it calls your
   output routine. The func argument is the address of a longword
   containing this code.

   The function code specifies the reason the symbiont is calling
   your output routine or, in other words, the function that the
   symbiont expects your routine to perform at this time.

   Most function codes require or allow additional information to
   be passed in the call via the funcdesc and funcarg arguments. The
   description of each output function code, therefore, includes a
   description of how these two arguments are used for that function
   code.

   The following list describes all the function codes that the
   symbiont might supply when it calls your output routine (function
   codes applicable only to input and formatting routines are
   explained in the descriptions of the user input routine and user
   formatting routine, respectively). Each programming language
   provides an appropriate mechanism for defining these function
   codes.
 

3  Function_Codes_for_Output_Routines
 

PSM$K_OPEN

   When the symbiont calls your output routine with this function
   code, your routine should prepare to move data to the device
   by performing such tasks as allocating the device, assigning a
   channel to the device, and so on. The next time the symbiont
   calls your output routine, the symbiont specifies one of the
   WRITE function codes (PSM$K_WRITE or PSM$K_WRITE_NOFORMAT).

   The symbiont calls your output routine with the PSM$K_OPEN
   function code when the symbiont receives the SMBMSG$K_START_
   STREAM message from the job controller.

   If your output routine returns an error condition value (low
   bit clear) to the PSM$K_OPEN function call, the job controller
   stops processing on the stream and reports the error to whomever
   entered the DCL command START/QUEUE.

   The funcdesc argument is the address of a descriptor that
   identifies the name of the device to which the output routine
   is to write. This device name is established by the DCL command
   INITIALIZE/QUEUE/ON=device.

   The funcarg argument is the address of a longword into which
   the user output routine returns the device status longword.
   Your output routine sets bits in the device status longword to
   indicate to the job controller whether the device falls into one
   of the following categories:

   o  Can print lowercase letters

   o  Is a terminal

   o  Is connected to the CPU by means of a modem (remote)

   If your output routine does not set any of these bits in the
   device status longword, the job controller assumes, by default,
   that the device is a line printer that prints only uppercase
   letters.
 

PSM$K_WRITE

   When the symbiont calls your routine with this function code,
   your routine must write data to the device. The symbiont
   supplies the data to be written in the funcdesc argument. Compaq
   recommends that you use one of the Run-Time Library string
   routines to access the data in the buffer described by the
   funcdesc argument.
 

PSM$K_WRITE_NOFORMAT

   When the symbiont calls your routine with this function code,
   your routine must write data to the device and must indicate to
   the device driver that the data is not to be formatted.

   The symbiont calls your routine with this function code when:
   (1)  the print request specifies the PASSALL option or (2) data
   is introduced by the ANSI DCS (device control string) escape
   sequence.

   The symbiont supplies the data to be written in the funcdesc
   argument. Compaq recommends that you use one of the Run-Time
   Library string routines to move the data from the descriptor to
   the device.

   The output routine of the symbiont informs the device driver not
   to format the data in the following way:

   o  When the device is a line printer, the symbiont's output
      routine specifies the IO$_WRITEPBLK function code when it
      calls the $QIO system service.

   o  When the device is a terminal, the symbiont's output routine
      specifies the IO$M_NOFORMAT function modifier when it calls
      the $QIO system serivce.
 

PSM$K_CANCEL

   When the symbiont calls your routine with this function code,
   your routine must abort any outstanding asynchronous I/O
   requests.

   The output routine supplied by the symbiont aborts outstanding
   I/O requests by calling the $CANCEL system service with the IO$_
   CANCEL function code.

   If your output routine returned the condition value PSM$_
   PENDING to one or more previous write requests that are still
   outstanding (that is, PSM$REPORT has not yet been called to
   report completion), then your output routine must call PSM$REPORT
   one time for each outstanding write request that is canceled with
   this call. That is, canceling an asynchronous write request does
   not relieve the user output routine of the requirement to call
   PSM$REPORT once for each asynchronous write request.

   You cannot use the funcdesc and funcarg arguments with this
   function code.
 

PSM$K_CLOSE

   When the symbiont calls your routine with this function code,
   your output routine must terminate processing and release any
   resources it allocated (for example, channels assigned to the
   device).

   You cannot use the funcdesc and funcarg arguments with this
   function code.
 

Other Output Function Codes

   The symbiont can call your output routine with other function
   codes. Your routine should return the status PSM$_FUNNOTSUP
   (function not supported) when it is called with any of the
   following function codes or with any undocumented function code.
   When the status PSM$_FUNNOTSUP is returned, the symbiont performs
   its normal action as if no output routine were supplied. To
   suppress the symbiont's normal action, you should return SS$_
   NORMAL.

   PSM$K_START_STREAM     PSM$K_STOP_STREAM
   PSM$K_START_TASK       PSM$K_PAUSE_TASK
   PSM$K_RESUME_TASK      PSM$K_STOP_TASK
   PSM$K_RESET_STREAM

   These function codes correspond to message items sent by the job
   controller to the symbiont.

   Other function codes correspond to internal symbiont mechanisms
   that are not part of the public interface to the print symbiont.

   Your output routine should return the status PSM$_FUNNOTSUP or
   SS$_NORMAL when it is called with a message function code or with
   a private function code.
 

funcdesc

   OpenVMS usage:char_string
   type:         character string
   access:       read only
   mechanism:    by descriptor
   Function descriptor supplying information related to the function
   specified by the func argument. The funcdesc argument is the
   address of this descriptor.

   The contents of the function descriptor can vary for each
   function. Refer to the description of each function code to
   determine the contents of the function descriptor. In some cases,
   the function descriptor is not used at all.
 

funcarg

   OpenVMS usage:user_arg
   type:         longword (unsigned)
   access:       read only
   mechanism:    by reference
   Function argument supplying information related to the function
   specified by the func argument. The funcarg argument is the
   address of a longword containing this function argument.

   The contents of the function argument can vary for each function.
   Refer to the description of each function code to determine the
   contents of the function argument. In some cases, the function
   argument is not used.
 

3  Condition_Values_Returned

   SS$_NORMAL         Normal successful completion. The user output
                      routine has completed the function that the
                      symbiont requested.
   PSM$_FUNNOTSUP     Function not supported. The user output
                      routine does not support or does not recognize
                      the function code supplied by the symbiont.
                      To ensure future compatibility, your output
                      routine should return this status for any
                      unrecognized status codes.
   PSM$_PENDING       Requested function accepted but not completed.
                      Your output routine can return this status
                      only with PSM$K_WRITE and PSM$K_WRITE_NOFORMAT
                      function calls. Further, if your routine
                      returns PSM$_PENDING, your routine must
                      eventually signal completion by way of the
                      PSM$REPORT routine. Refer to the description
                      of the PSM$REPORT routine for more information
                      about asynchronous write operations and the
                      PSM$_PENDING condition value.

   This routine also returns any error condition values that you
   have coded your output routine to return.