Line Output Processing : ncodefld: and writeline:
The basic procedure for outputting line data (i.e. character information) is
standard in any computer language. First, numeric information must be encoded
into character data according to a specified format; alphanumeric data (i.e.
headers, etc.) are added; and the line is sent to a particular output device.
Exactly the same process is employed in Xtal programs. The actual structure of
this process is, however, quite different to Fortran formatting and writing.
The reasons for this are similar to those for line inputting; greater
flexibility; consolidation of outputting software in the nucleus; improved
portability (some Fortran formatting features are very machine specific); and
lastly the provision of more powerful outputting tools.
Outputting is effectively the reverse of inputting. The input line is read
into the character buffer CHRIP and decoded into floating-point buffer BUFIN.
To output, numerical data it is stored in the floating-point buffer BUFOT and
encoded into character strings in CHROT. Additional character data, such as
headers, are inserted into CHROT before it is sent to the output device.
Here are the principal macros used in the outputting process:
ncodefld: |
converts real numbers into character strings, using a wide range offormat controls and predefined format lists. |
movechar:
|
and movertoc: are used to insert character strings into the outputbuffer (CHROT or any other character buffer). |
writeline:
|
is used to send character buffers to one or more of the lineoutput devices. It also serves a number of functions to do with pagination,headings and print priorities. |
Only the broad concept of outputting lines will be considered here. Details of
the options for the line output macros are provided in the next chapter. Xtal
programs use a variety of character buffers, into which numerical information
can be encoded and alphanumerical information can be stored before being sent
to an output device. Unlike the Fortran approach, the 'putting' step in Xtal is
kept quite separate from the 'formatting or editing' process. This may appear
cumbersome but it has important offsetting advantages. For example, character
strings and buffers can be used for more than one purpose; buffers set up for
one output device can be used for another (e.g. the lineprinter and the 'punch'
file); there is much more flexibility in using dynamic 'formats' (e.g. either
numerical encoding formats which are generated, or the positioning of
'graphing' characters).
ncodefld:(REAL, N, CHAR, FMT, M)
ncodefld: is the encoding or formatting command. The sequence of M real
numbers in the real array REAL, starting at the value in REAL(N), are encoded
and stored in the character array CHAR using format codes from the real array
FMT.
The format codes are described in detail in the definitions below. They take
two basic forms: column-specific or stacked. If the packed-integer format code
contains a column value then this specifies the right-most character of the
output number. If it does not then the right most character position is
calculated by adding the width value from the format code to LCHROT (the system
variable containing the current length of the output line buffer CHROT). In
this way encoded numbers are stacked into CHROT, from left to right. If a given
number 'overflows' the specified format ncodefld: will vary other format
parameters (including the format type) in an attempt to fit the number within
the format width.
Here are three examples. The first
ncodefld:(BUFOT,3,CHROT,FMT2,5)
encodes the five values BUFOT(3) to BUFOT(7) into the standard output array
CHROT using the format codes FMT2(1) to FMT2(5). The second example
ncodefld:(FLOAT(I),1,R23,360423.,1)
encodes the value I into the character array with a format which places the
right-most digit into column 36; allows for a maximum of 4 digits; forces at
least two digits to be output (including zeros); and uses integer type format.
The third example
ncodefld:(FMAX,1,CHROT,622.,1)
places the formatted value (equivalent to F6.2) of FMAX into the array CHROT in
the character positions LCHROT+1 to LCHROT+6.
movechar:(CHR1, NC1, CHR2, NC2, LEN, KEY)
movertoc:(REAL, NC1, CHR2, NC2, LEN, KEY)
The movechar: and movertoc: macros are general character string movers. They
are often used in the outputting process to insert character information into a
character buffer that will be acted on by writeline:. Here are two typical
examples.
movechar:(HEAD1,1,CHROT,22,30,0)
moves characters 1 to 30 of HEAD1 to characters 22 to 51 of the standard output
buffer CHROT. The key of zero signals normal transfer (see the next chapter for
details). In the next example movertoc:(QX(MARKA+5),1,CHROT,2,8,0)
an 8-character string is transfered from the real array QX, starting at
character 1 of the array element QX(MARKA+5), into characters 2 to 9 of the
output buffer CHROT. This is a typical operation when preparing to output the
atom name from the atom list stored in the general data storage array.
writeline:(BLINE, CHAR, NCHR, KEY, PRIOR)
writeline: performs a number of outputting control functions, in addition to
putting character buffers to the print file ioprt:. The writeline: arguments
are: BLINE, the number of blank lines to be output before the character buffer
is output; CHAR, the name of a character output array, of length NCHR; KEY,
specifies which character buffers are to be output; and PRIOR, specifies the
print priority. Full details of these parameters are given in the next chapter.
Here we will consider only the general principles and give several typical
applications. The first example
writeline:(0,0,0,1,3)
shows a common application of writeline: It will cause CHROT to be printed
provided that the value of the print priority level PPRIOR is 3 (standard) or
greater. Repetitive application of this statement (e.g. inside a loop) will
produce a list of CHROT lines. No blank lines will be inserted. writeline:
tests the system variable LINCT to make sure each line will fit on the current
page; otherwise the page is ejected and the page header is output before CHROT
is output. Note that if KEY is negative, the page header will not be printed.
Page counters are automatically incremented. The programmer can control
pagination by setting the value of LINCT and LINRM. The 'lines remaining'
parameter LINRM specifies the minimum number of lines that must be available on
the current page before the next line will be output. This provides a way of
ensuring that a block of output lines, such as a graph, will appear on the same
page. LINRM is automatically reset to zero at the top of each page.
The second example
writeline:(0,HEAD,NHEAD,1,3)
is the same application as above except a list header line is also output at
the start of each page and when LINRM is non-zero. If the programmer sets LINRM
to the number of lines required to start a list, HEAD will be output on the
first encounter with writeline: (this causes LINRM to be reset to zero) and at
the start of every new page. The next example
writeline:(1,HEAD3,30,2,3)
is typical of a non-repetitive application (KEY=2). Three lines are output: a
blank line; a line containing HEAD3 (to a length of 30 characters); and the
standard buffer CHROT. This application is commonly used to output a major
header line with an underline which was inserted into CHROT using movechar:.
The last example
writeline:(2,MES,NMES,3,3)
outputs the auxiliary buffer MES, preceded by two blank lines. CHROT is not
output.
Here is a typical sequence of instructions used to output header and numeric
information.
chardata:(S4,-)#
chardata:(S9, METRIC TENSOR OF VECTORS)#
realdata:(FMT,[211142.,321142.,431142.])#
datastuff:#
..........
LINRM=6# Require 6 lines on a page
movchar:(S4,1,CHROT,2,NS9-1,1)# Put -'s into CHROT
writeline:(1,S9,NS9,2,3)# Output header with underline
DO J=1,9,3# Loop thru matrix GS
$(# >>>>>>>>>>>>>>>>>>>>>>>>>>> 6
ncodefld:(GS,J,CHROT,FMT,3)# Format three vectors
writeline:(0,0,0,1,3)# Output three vectors/line
$)# <<<<<<<<<<<<<<<<<<<<<<<<<<< 6