VMS Help  —  PSM Routines
    The print symbiont modification (PSM) routines allow you to
    modify the behavior of the print symbiont supplied with the
    operating system.

1  –  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]

1.1  –  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.

1.2  –  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

1.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.

1.4  –  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

2.1  –  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.

2.2  –  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.

2.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).

2.4  –  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.

3  –  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.1  –  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.2  –  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.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.4  –  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.5  –  Condition Value Returned

    SS$_NORMAL         Normal successful completion.

4  –  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]

4.1  –  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.

4.2  –  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 help topic describes this
    procedure in greater detail.

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

4.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.

4.4  –  Condition Value Returned

    SS$_NORMAL         Normal successful completion.

5  –  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

5.1  –  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.

5.2  –  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:

    31           23          15             7           0
    -----------------------------------------------------
    |  Character  |   Count   |  Character  |   Count   |
    -----------------------------------------------------
         Trailing Carriage          Leading Carriage
        Control Information        Control Information

    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 help topic 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 for more information.

5.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.

5.4  –  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.

6  –  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

6.1  –  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.

6.2  –  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.

6.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. HP 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. HP 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.

6.4  –  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.

7  –  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

7.1  –  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.

7.2  –  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.

7.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. HP 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. HP 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.

7.4  –  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.
Close Help