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.

Line output example

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