diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /pkg/tbtables/tbzrds.x | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'pkg/tbtables/tbzrds.x')
-rw-r--r-- | pkg/tbtables/tbzrds.x | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/pkg/tbtables/tbzrds.x b/pkg/tbtables/tbzrds.x new file mode 100644 index 00000000..16cbd977 --- /dev/null +++ b/pkg/tbtables/tbzrds.x @@ -0,0 +1,162 @@ +include <mach.h> # for MAX_DIGITS, NDIGITS_DP and SZB_CHAR +include <tbset.h> +include "tbtables.h" +include "tbltext.h" + +define MAX_WIDTH_INT 11 # maximum width of integer field + +# tbzrds -- read a (simple) text file into memory +# +# When the first non-comment line is read, tbzcol is called to figure out +# the data types, to get initial info about precision, and to create columns +# and allocate memory for column values. +# +# The input buffer buf will likely already contain the first data line of +# the file when this routine is called. (If not, buf will have been set +# to EOS.) This is because the beginning of the file is read to determine +# whether it is a simple text table or one with explicit column definitions. +# +# For each data line (including the first), tbzmem is called to read values +# into memory. It updates the column widths in case values are wider than in +# the first row. tbzmem also reallocates buffers, if necessary, and updates +# the number of rows. +# +# The print format is set by this routine, and maximum values are set +# for the widths of double precision and integer columns. COL_LEN is +# also set here, since columns are defined based on values in the first +# row, and the data type or width of a character column can change after +# the first row. +# +# This version is for simple text tables. The version that is appropriate +# for a table with explicit column definitions is tbzrdx. +# +# Phil Hodge, 7-Jun-1999 Subroutine created, based on tbzopn. +# Phil Hodge, 5-Aug-1999 Assign COL_NELEM = 1. + +procedure tbzrds (tp, buf, line, line_type) + +pointer tp # i: pointer to table descriptor +char buf[ARB] # io: buffer for input line +int line # io: line number in input file +int line_type # io: type of line read by tbzlin +#-- +pointer sp +pointer wid # pointer to array of values of width +pointer prec # pointer to array of values of precision +pointer fmt_code # pointer to array of format codes +pointer cp # pointer to column descriptor +char pform[SZ_COLFMT] # print format +int fd # fd for the file +int width # width of field for printing +int precision # for print format +int row # row number (can be from more than one line) +int colnum # column number +bool first # is current line the first non-comment line? +bool done +int nchar, tbzlin() # reads a line from the file +errchk tbcfmt, tbzlin, tbzcol, tbzmem, tbzkey + +begin + call smark (sp) + + # Read the file into memory. + fd = TB_FILE(tp) + first = true + row = 0 + + done = false + + # If the input buffer is empty, read the first line. + if (buf[1] == EOS) { + nchar = tbzlin (fd, buf, SZ_TEXTBUF, line, line_type) + if (nchar == EOF) + done = true + } + + while (!done) { + + if (line_type == COMMENT_LINE) { + + call tbbcmt (tp, buf) # append to comment buffer + + } else if (line_type == KEYWORD_LINE) { + + call tbzkey (tp, buf, 0) # append to list of keywords + + } else if (line_type == COLDEF_LINE) { + + call error (1, + "tbtopn: column definitions must precede all data lines") + + } else if (line_type == DATA_LINE) { + + row = row + 1 + + if (first) { + # Get initial column definitions from first row. + call tbzcol (tp, buf, wid, prec, fmt_code) + first = false + } + + # Read data into memory. + call tbzmem (tp, buf, row, line, + Memi[wid], Memi[prec], Memc[fmt_code]) + } else { + call error (1, "tbzrds: internal error") + } + + # Read the next line. + nchar = tbzlin (fd, buf, SZ_TEXTBUF, line, line_type) + if (nchar == EOF) + done = true + } + + # Set print formats and data lengths. + pform[1] = '%' + do colnum = 1, TB_NCOLS(tp) { + cp = TB_COLINFO(tp,colnum) + + width = Memi[wid+colnum-1] + + # The format code fmt_code is used for double because it could + # be g or h or m, but it is ignored for int and char. + if (COL_DTYPE(cp) == TBL_TY_DOUBLE) { + width = min (width, MAX_DIGITS) + precision = Memi[prec+colnum-1] + if (Memc[fmt_code+colnum-1] == 'g') + precision = max (precision, width-2) # maximum precision + precision = min (precision, NDIGITS_DP) + call sprintf (pform[2], SZ_COLFMT-1, "%d.%d%c") + call pargi (width) + call pargi (precision) + call pargc (Memc[fmt_code+colnum-1]) + + COL_LEN(cp) = SZ_DOUBLE + + } else if (COL_DTYPE(cp) == TBL_TY_INT) { + width = min (width, MAX_WIDTH_INT) + call sprintf (pform[2], SZ_COLFMT-1, "%dd") + call pargi (width) + + COL_LEN(cp) = SZ_INT32 + + } else { # character string + call sprintf (pform[2], SZ_COLFMT-1, "-%ds") + call pargi (width) + + COL_LEN(cp) = (width + SZB_CHAR-1) / SZB_CHAR + } + + # Set the print format for this column. + call strcpy (pform, COL_FMT(cp), SZ_COLFMT) + + COL_NELEM(cp) = 1 # ascii tables do not support arrays + } + + # Free memory allocated by tbzcol. + call mfree (fmt_code, TY_CHAR) + call mfree (prec, TY_INT) + call mfree (wid, TY_INT) + + call sfree (sp) +end |