.TITLE FPRINT ;; ; INTEGER FUNCTION FPRINT ( format , value1 , value2 , ... ) ; ; ; Prints a line which is built using the $FAO system service instead ; of a FORMAT statement. The advantage of doing this is that $FAO ; prints numberic values using exactly enough columns to display the ; number; you will never get 'value too large for field' errors or ; have extra white space in front of a number. Also, $FAO can auto- ; matically decide whether to put an 's' in a print line, like: ; ; '1 Error Occurred' '2 Errors Occurred' ; ; The first argument to FPRINT must be a $FAO format control string. ; Section 12.1 and pages 107-110 of the VAX/VMS System Services Ref- ; erence Manual describe these strings. The remaining arguments are ; variable values (either integers or character strings) to be prin- ; ted. Integer and string values can be freely intermixed; FPRINT ; is smart enough to tell an integer from a string. Example: ; ; CALL FPRINT('!UL Error!%S Occured in !AS',NERR,'XSUB') ; ^ ^ ; Integer String ; ; The first character of the resultant line is used as the carriage ; control character. ; ; FPRINT calls a routine named FPRINT_2 to actually print the line ; after $FAO builds it. You may provide your own FPRINT_2 if you ; want, for instance, to write to a file other than SYS$OUTPUT. The ; routine must use one argument, a variable-length character string, ; as, for example: ; ; INTEGER FUNCTION FPRINT_2(STRING) ; CHARACTER*(*) STRING ; WRITE (3,1000) STRING ; FPRINT_2 = 1 ; 1000 FORMAT (A) ; END ; ; Note that FPRINT_2 must be a function, returning a VMS status val- ; ue ('success' is 1). The function result of FPRINT is also a VMS ; status value; if $FAO fails, this is the value returned from $FAO; ; otherwise this is the value returned from FPRINT_2. ; ; FPRINT will not work correctly if any of the VALUEi arguments are ; integers with hex values '010Ennnn' (where n is any digit). ; ; .INDEX FORMATTING OUTPUT>> ; ; Alan L. Zirkle Naval Surface Weapons Center ; Code K53 ; 10 Aug 1984 Dahlgren, Virginia 22448 ; .PSECT $CODE, LONG,PIC,SHR,EXE,RD,NOWRT .ENTRY FPRINT, ^M MOVZBL (AP), R0 ; R0 = Count of arguments LOOP: ; Build parameter list for $FAOL on stack MOVL (AP)[R0], R1 ; R1 = Address of (i)th value MOVW 2(R1), R2 ; R2 = upper 16 bits of value or descriptor CMPW R2, #^X010E ; Is this a string descriptor? BEQL DESCR ; Branch if it is PUSHL (R1) ; Push %VAL of integer value on stack BRB LOOPEND DESCR: ; (i)th value is a character string PUSHL R1 ; Push address of string descriptor on stack LOOPEND: ; loop through all arguments from the last ACBL #2,#-1,R0,LOOP ; down to the second MOVL 4(AP), ARG1 ; 1st argument to FPRINT also 1st to $FAOL MOVL SP, ARG4 ; 4th argument to $FAOL is our stacked list MOVL #256, OUT ; Output buffer is 256 bytes long SUBL2 #256, SP ; Create output buffer on the stack MOVL SP, OUT2 ; Save buffer address in its descriptor CALLG ARGS, G^SYS$FAOL ; Call $FAOL system service BLBC R0, RETURN ; Quit now if $FAOL failed PUSHAW OUT ; Argument to FPRINT_2 is buffer descriptor CALLS #1, G^FPRINT_2 ; Call FPRINT_2 to print the resultant line RETURN: RET ; Return to calling program .PSECT $LOCAL, LONG,PIC,NOSHR,NOEXE,RD,WRT ARGS: ; Argument list for call to $FAOL .LONG 4 ; $FAOL requires 4 arguments ARG1: .LONG ; Format control string descriptor ARG2: .ADDRESS OUT ; Address of word to get resultant length ARG3: .ADDRESS OUT ; Address of output buffer string descriptor ARG4: .LONG ; Address of parameter list OUT: ; Output buffer descriptor .WORD ^X010E ; Fixed length string .WORD ; Length of output buffer OUT2: .LONG ; Address of output buffer .END