diff options
Diffstat (limited to 'pkg/utilities/nttools/tprint')
-rw-r--r-- | pkg/utilities/nttools/tprint/mkpkg | 15 | ||||
-rw-r--r-- | pkg/utilities/nttools/tprint/notes | 40 | ||||
-rw-r--r-- | pkg/utilities/nttools/tprint/tdump.x | 486 | ||||
-rw-r--r-- | pkg/utilities/nttools/tprint/tprhtml.x | 592 | ||||
-rw-r--r-- | pkg/utilities/nttools/tprint/tprint.h | 5 | ||||
-rw-r--r-- | pkg/utilities/nttools/tprint/tprint.x | 535 | ||||
-rw-r--r-- | pkg/utilities/nttools/tprint/tprlatex.x | 579 | ||||
-rw-r--r-- | pkg/utilities/nttools/tprint/tprplain.x | 530 |
8 files changed, 2782 insertions, 0 deletions
diff --git a/pkg/utilities/nttools/tprint/mkpkg b/pkg/utilities/nttools/tprint/mkpkg new file mode 100644 index 00000000..8134ff5b --- /dev/null +++ b/pkg/utilities/nttools/tprint/mkpkg @@ -0,0 +1,15 @@ +# Update tprint and tdump in the ttools package library. +# Author: HODGE, 2-FEB-1988 + +$checkout libpkg.a ../ +$update libpkg.a +$checkin libpkg.a ../ +$exit + +libpkg.a: + tdump.x <tbset.h> + tprint.x <time.h> <finfo.h> <tbset.h> + tprhtml.x <tbset.h> tprint.h + tprplain.x <tbset.h> tprint.h + tprlatex.x <tbset.h> tprint.h + ; diff --git a/pkg/utilities/nttools/tprint/notes b/pkg/utilities/nttools/tprint/notes new file mode 100644 index 00000000..2e6f9ff0 --- /dev/null +++ b/pkg/utilities/nttools/tprint/notes @@ -0,0 +1,40 @@ + Structure chart for tprint: 1988 Jan 21 + +tprint: + (tbtopn) + tpr_fm_date: + (finfo) + tpr_param_pr: + (tbhgnp) + tpr_data_pr: + (tctexp) + tpr_plain_pr: + (decode_ranges) + get_page: + (tbcigi) + tpr_pfmt: + (tbcigt) + tpr_cnames_pr: + (tbcigt) + (get_next_number) + prt_row + (tbcigi) + (tbegt[]) + tpr_latex_pr: + (decode_ranges) + tpr_pfmt: + (tbcigt) + tpr_beg_doc + tpr_def + tpr_begin_tbl + tpr_cnames_pr_l: + tpr_w_colsep + (tbcigt) + (get_next_number) + tpr_end_tbl + prt_row_l: + tpr_w_colsep + (tbcigi) + (tbegt[]) + tpr_end_doc + (tbtclo) diff --git a/pkg/utilities/nttools/tprint/tdump.x b/pkg/utilities/nttools/tprint/tdump.x new file mode 100644 index 00000000..54658d58 --- /dev/null +++ b/pkg/utilities/nttools/tprint/tdump.x @@ -0,0 +1,486 @@ +include <tbset.h> + +# tdump -- Program to dump a table. +# This differs from tprint in several ways: column names and row numbers +# are not printed, and all columns for a given row are printed (possibly on +# several lines) before moving on to the next row. Also, g format is used +# for floating-point numbers (%15.7g for real, %24.16g for double) regardless +# of the format specification for the column. This is to prevent loss of +# precision. +# +# Phil Hodge, 31-Jul-1987 Task created +# Phil Hodge, 11-Aug-1987 Modify d_gt_col_ptr for datatype=-n for char string. +# Phil Hodge, 30-Dec-1987 Use tctexp for column names. +# Phil Hodge, 7-Sep-1988 Change parameter name for table. +# Phil Hodge, 21-Dec-1988 Also print column descrip; use g format for data. +# Phil Hodge, 9-Mar-1989 Change type of dtype in tbhgnp from char to int. +# Phil Hodge, 9-Jul-1991 Rename parameter pagwidth to pwidth. +# Phil Hodge, 2-Apr-1993 Include short datatype in td_col_def. +# Phil Hodge, 2-Jun-1994 In td_col_ptr, include newline in warning message. +# Phil Hodge, 12-Dec-1994 Include array size in column definitions; +# increase SZ_DTYPE from 9 to 29; +# dump all elements if column is an array. +# Phil Hodge, 15-Dec-1994 Increase size of file names from SZ_FNAME to SZ_LINE. +# Phil Hodge, 13-Jan-1995 Change calling sequence of inquotes. +# Phil Hodge, 19-Jul-1995 Add tp to calling sequence of tl_dtype in td_col_def. +# Phil Hodge, 4-Apr-1996 In td_p_data, start each array at beginning of line; +# change formats for real & double to %13.7g, %22.16g. +# Phil Hodge, 5-Jun-1997 If keywords are to be printed, also print comments. +# Phil Hodge, 20-Jul-1998 Print '' instead of blank for null keywords. +# Phil Hodge, 22-Jul-1998 Left justify strings and boolean elements. +# Phil Hodge, 2-Nov-2000 Use pwidth < 1 to disable the test on page width. +# Phil Hodge, 15-May-2002 Use a specific format for int and short columns; +# this was needed because for x or o format the printed +# values could be misleading. + +define SZ_FMT 16 # size of string containing print format +define FMT_REAL "%13.7g" # format for printing a real +define SPACE_REAL 13 # space required for printing a real +define FMT_DBL "%22.16g" # format for printing a double +define SPACE_DBL 22 # space required for printing a double +define FMT_INT "%11d" # format for printing an int +define SPACE_INT 11 # space required for printing an int +define FMT_SHORT "%5d" # format for printing a short +define SPACE_SHORT 5 # space required for printing a short +define MAX_RANGES (SZ_LINE/2) # max number of ranges of row numbers +define SZ_DTYPE 29 # size of string containing column data type +define SZ_LBUF 2 * SZ_LINE + 1 + +procedure tdump() +#-- +pointer tp # pointer to input table descr +pointer cptr # scratch for array of column pointers +pointer tname # scratch for table name +pointer cname, pname, dname # scratch for names of output files +pointer upar # scratch for header keyword value +pointer comment # scratch for header keyword comment +pointer datatype # scr for array of data types of columns +pointer nelem # scr for array of array lengths of columns +pointer len_fmt # scr for array of lengths of print formats +pointer pformat # scratch for array of print formats +pointer columns # list of columns to be dumped +pointer r_str # string which gives ranges of row numbers +char keyword[SZ_KEYWORD] # buffer for user parameter keyword +char char_type # data type as a letter (t, b, i, r, d) +pointer sp # stack pointer +int fd # file descr for output user param, data +int n # loop index for user parameters +int dtype # data type (TY_CHAR, etc) +int npar # number of user parameters +int nrows, ncols # number of rows and columns in table +int nprint # number of columns to print (may be < ncols) +int pagewidth # page width +bool prcoldef # print column definitions? +bool prparam, prdata # print user parameters? data? +pointer tbtopn() +int open(), clgeti(), tbpsta() + +begin + call smark (sp) + call salloc (tname, SZ_LINE, TY_CHAR) + call salloc (cname, SZ_LINE, TY_CHAR) + call salloc (pname, SZ_LINE, TY_CHAR) + call salloc (dname, SZ_LINE, TY_CHAR) + call clgstr ("table", Memc[tname], SZ_LINE) + + # Get the names of the output files. If a name is null, don't + # write the corresponding portion of the table. + call clgstr ("cdfile", Memc[cname], SZ_LINE) + call clgstr ("pfile", Memc[pname], SZ_LINE) + call clgstr ("datafile", Memc[dname], SZ_LINE) + prcoldef = (Memc[cname] != EOS) + prparam = (Memc[pname] != EOS) + prdata = (Memc[dname] != EOS) + if (!prcoldef && !prparam && !prdata) { + call sfree (sp) # nothing to do + return + } + + tp = tbtopn (Memc[tname], READ_ONLY, 0) + + if (prcoldef || prdata) { + + # If we are to print column definitions and/or data, + # allocate memory and get list of columns. + + call salloc (columns, SZ_LINE, TY_CHAR) + call clgstr ("columns", Memc[columns], SZ_LINE) + ncols = tbpsta (tp, TBL_NCOLS) + + # Allocate enough scratch space for printing all columns. + call salloc (cptr, ncols, TY_POINTER) + call salloc (len_fmt, ncols, TY_INT) + call salloc (datatype, ncols, TY_INT) + call salloc (nelem, ncols, TY_INT) + } + + if (prcoldef) { + + # Open the output file for the column definitions. + fd = open (Memc[cname], NEW_FILE, TEXT_FILE) + + # Print column definitions. + call td_col_def (tp, fd, Memc[columns], Memi[cptr]) + + call close (fd) # column definitions have been written + } + + if (prparam) { + + # Print header parameters. + npar = tbpsta (tp, TBL_NPAR) + if (npar > 0) { + fd = open (Memc[pname], NEW_FILE, TEXT_FILE) + call salloc (upar, SZ_PARREC, TY_CHAR) + call salloc (comment, SZ_PARREC, TY_CHAR) + do n = 1, npar { + # Get the Nth user parameter, and print it. + call tbhgnp (tp, n, keyword, dtype, Memc[upar]) + call tbhgcm (tp, keyword, Memc[comment], SZ_PARREC) + switch (dtype) { + case TY_REAL: + char_type = 'r' + case TY_INT: + char_type = 'i' + case TY_DOUBLE: + char_type = 'd' + case TY_BOOL: + char_type = 'b' + default: + char_type = 't' + } + if (keyword[1] == EOS) { + call fprintf (fd, "'' ") + } else { + call fprintf (fd, "%-8s") + call pargstr (keyword) + } + call fprintf (fd, " %c") + call pargc (char_type) + if (Memc[comment] == EOS) { + call fprintf (fd, " %s\n") + call pargstr (Memc[upar]) + } else { # also print comment + if (char_type == 't') { + call fprintf (fd, " '%s'") # enclose text in quotes + call pargstr (Memc[upar]) + } else { + call fprintf (fd, " %s") # no quotes needed + call pargstr (Memc[upar]) + } + call fprintf (fd, " %s\n") + call pargstr (Memc[comment]) + } + } + call close (fd) # header parameters have been written + } + } + + if (prdata) { + + # Print data portion of table. + nrows = tbpsta (tp, TBL_NROWS) + + if ((nrows < 1) || (ncols < 1)) { + call eprintf ("table is empty\n") + call tbtclo (tp) + call sfree (sp) + return # nothing more to do + } + # Open the output file for the table data. + fd = open (Memc[dname], NEW_FILE, TEXT_FILE) + + call salloc (r_str, SZ_LINE, TY_CHAR) + call clgstr ("rows", Memc[r_str], SZ_LINE) + + pagewidth = clgeti ("pwidth") + if (IS_INDEF(pagewidth)) + pagewidth = -1 # no limit on page width + + # Get column pointers, formats, etc for all columns that are + # to be printed. + call td_col_ptr (tp, Memc[columns], pagewidth, Memi[cptr], + Memi[len_fmt], Memi[datatype], Memi[nelem], nprint) + + if (nprint > 0) { + # Allocate scratch space for print format. (one char for EOS) + call salloc (pformat, (SZ_FMT+1)*nprint, TY_CHAR) + # Print the values in the table. + call td_p_data (tp, fd, Memi[cptr], Memc[r_str], + Memi[len_fmt], Memi[datatype], Memi[nelem], + Memc[pformat], pagewidth, nprint) + } + call close (fd) # data values have been printed + } + call tbtclo (tp) + call sfree (sp) +end + + + +# td_col_def -- print column definitions +# This routine prints the column name, data type, print format, and units +# for all columns that were specified by the user. + +procedure td_col_def (tp, fd, columns, cptr) + +pointer tp # i: pointer to table descriptor +int fd # i: fd for output file +char columns[ARB] # i: list of columns to be dumped +pointer cptr[ARB] # o: array of pointers to column descriptors +#-- +pointer sp +pointer cname, cunits, cfmt # pointers to scratch space for column info +char chartyp[SZ_DTYPE] # data type expressed as a string +int ncols # the total number of columns in the table +int nprint # number of columns to print +int dtype # data type of a column +int nelem # array length +int lenformat # (ignored) +int colnum # column number (ignored) +int k # loop index +int tbpsta() + +begin + call smark (sp) + call salloc (cname, SZ_FNAME, TY_CHAR) + call salloc (cunits, SZ_FNAME, TY_CHAR) + call salloc (cfmt, SZ_COLFMT, TY_CHAR) + + ncols = tbpsta (tp, TBL_NCOLS) + + # Get column pointers for all columns that are to be dumped. + call tctexp (tp, columns, ncols, nprint, cptr) + + # Do for each column that is to be printed. + do k = 1, nprint { + call tbcinf (cptr[k], + colnum, Memc[cname], Memc[cunits], Memc[cfmt], + dtype, nelem, lenformat) + + # Enclose column name in quotes if it contains embedded + # or trailing blanks. + call inquotes (Memc[cname], Memc[cname], SZ_FNAME, YES) + call fprintf (fd, "%-16s") # but name can be longer + call pargstr (Memc[cname]) + + # Print data type. First convert integer data type code to a + # character string, and append info about array size if > 1. + call tl_dtype (tp, cptr[k], dtype, nelem, chartyp, SZ_DTYPE) + call fprintf (fd, " %-8s") + call pargstr (chartyp) + + # Print the format for display. + call fprintf (fd, " %8s") + call pargstr (Memc[cfmt]) + + # Print column units. Ignore trailing blanks. + call inquotes (Memc[cunits], Memc[cunits], SZ_FNAME, NO) + call fprintf (fd, " %s") + call pargstr (Memc[cunits]) + call fprintf (fd, "\n") # end of line for each column + } + call sfree (sp) +end + + +# td_col_ptr -- get column pointers +# This routine gets an array of pointers to the descriptors of those +# columns that are to be printed, plus other info. + +procedure td_col_ptr (tp, columns, pagewidth, + cptr, len_fmt, datatype, nelem, nprint) + +pointer tp # i: pointer to table descriptor +char columns[ARB] # i: list of columns to be dumped +int pagewidth # i: page width (to make sure it's wide enough) +pointer cptr[ARB] # o: array of pointers to column descriptors +int len_fmt[ARB] # o: length of print format for each column +int datatype[ARB] # o: data type for each column +int nelem[ARB] # o: array length of each column +int nprint # o: number of columns to print +#-- +char colname[SZ_COLNAME] # column name for possible error message +int ncols # total number of columns in the table +int k # loop index +int tbpsta(), tbcigi() + +begin + ncols = tbpsta (tp, TBL_NCOLS) + + # Get column pointers for all columns that are to be dumped. + call tctexp (tp, columns, ncols, nprint, cptr) + + # For each column that is to be printed, get the length of the print + # format, and if the column type is string then increase the length + # of the print format by two for possible enclosing quotes. + do k = 1, nprint { + + datatype[k] = tbcigi (cptr[k], TBL_COL_DATATYPE) + nelem[k] = tbcigi (cptr[k], TBL_COL_LENDATA) + + if (datatype[k] == TY_REAL) + len_fmt[k] = SPACE_REAL + else if (datatype[k] == TY_DOUBLE) + len_fmt[k] = SPACE_DBL + else if (datatype[k] == TY_INT) + len_fmt[k] = SPACE_INT + else if (datatype[k] == TY_SHORT) + len_fmt[k] = SPACE_SHORT + else + len_fmt[k] = tbcigi (cptr[k], TBL_COL_FMTLEN) + + if (datatype[k] < 0) # char string column + len_fmt[k] = len_fmt[k] + 2 + + if (pagewidth > 0 && len_fmt[k] > pagewidth) { + call tbcigt (cptr[k], TBL_COL_NAME, colname, SZ_COLNAME) + call eprintf ("Page width is too small for column `%s'.\n") + call pargstr (colname) + } + } +end + + +# td_p_data -- print the contents of the table +# The data in the table are printed one row at a time. + +procedure td_p_data (tp, fd, cptr, range_string, + len_fmt, datatype, nelem, + pformat, pagewidth, nprint) + +pointer tp # i: pointer to table descriptor +int fd # i: fd for output file +pointer cptr[nprint] # i: array of pointers to column descriptors +char range_string[ARB] # i: string which gives ranges of row numbers +int datatype[nprint] # i: array of flags: true if column is a string +int nelem[ARB] # i: array length of each column +int len_fmt[nprint] # i: array of lengths of print formats +char pformat[SZ_FMT,nprint] # io: scratch space for print formats +int pagewidth # i: page width +int nprint # i: number of columns to print +#-- +pointer sp +pointer lbuf # scratch space for line buffer +double dbuf # buffer for double-precision value +real rbuf # buffer for single-precision value +int ibuf # buffer for integer value +short sbuf # buffer for short value +int nrows # number of rows in the table +int rownum, k # loop indices for row, column +int j # loop index for array element +int line_len # current line length +int ranges[3,MAX_RANGES] # ranges of row numbers +int nvalues # returned by decode_ranges and ignored +int stat # returned by get_next_number +bool done # flag for terminating loop +int decode_ranges(), get_next_number() +int tbpsta(), tbagtr(), tbagtd(), tbagti(), tbagts(), tbagtt() +string MISSING "error reading data from table" + +begin + nrows = tbpsta (tp, TBL_NROWS) + + if (decode_ranges (range_string, ranges, MAX_RANGES, nvalues) != 0) { + call eprintf ("bad range of row numbers\n") + return + } + + call smark (sp) + call salloc (lbuf, SZ_LBUF, TY_CHAR) + + # This section gets the print format for each column. The + # format is just "%Ns" or "%-Ns". + do k = 1, nprint { + pformat[1,k] = '%' + if (datatype[k] < 0 || datatype[k] == TY_BOOL) { + call sprintf (pformat[2,k], SZ_FMT-1, "-%ds") # left justify + call pargi (len_fmt[k]) + } else { + call sprintf (pformat[2,k], SZ_FMT-1, "%ds") + call pargi (len_fmt[k]) + } + } + + # This section prints the data. + rownum = 0 # initialize get_next_number + line_len = 0 + done = false + while ( !done ) { + + stat = get_next_number (ranges, rownum) + if ((stat == EOF) || (rownum > nrows)) { + done = true + + } else { + + # Print values in current row. The loop on k is for each + # column that is to be printed. + do k = 1, nprint { + + # If the current column contains arrays, print each + # element, and start at the beginning of the line. + if (nelem[k] > 1 && line_len > 0) { + call fprintf (fd, "\n") + line_len = 0 # reset after newline + } + do j = 1, nelem[k] { + + # If we have previously printed something on the + # current line, print either a space or newline, + # depending on how close we are to the end of the line. + if (line_len > 1) { + if (pagewidth > 0 && + line_len + len_fmt[k] >= pagewidth) { + # need to start a new line + call fprintf (fd, "\n") + line_len = 0 + } else { + # continue on current line + call fprintf (fd, " ") + line_len = line_len + 1 + } + } + + if (datatype[k] == TY_REAL) { + if (tbagtr (tp, cptr[k], rownum, rbuf, j, 1) < 1) + call error (1, MISSING) + call sprintf (Memc[lbuf], SZ_LBUF, FMT_REAL) + call pargr (rbuf) + } else if (datatype[k] == TY_DOUBLE) { + if (tbagtd (tp, cptr[k], rownum, dbuf, j, 1) < 1) + call error (1, MISSING) + call sprintf (Memc[lbuf], SZ_LBUF, FMT_DBL) + call pargd (dbuf) + } else if (datatype[k] == TY_INT) { + if (tbagti (tp, cptr[k], rownum, ibuf, j, 1) < 1) + call error (1, MISSING) + call sprintf (Memc[lbuf], SZ_LBUF, FMT_INT) + call pargi (ibuf) + } else if (datatype[k] == TY_SHORT) { + if (tbagts (tp, cptr[k], rownum, sbuf, j, 1) < 1) + call error (1, MISSING) + call sprintf (Memc[lbuf], SZ_LBUF, FMT_SHORT) + call pargs (sbuf) + } else { + if (tbagtt (tp, cptr[k], rownum, + Memc[lbuf], SZ_LBUF, j, 1) < 1) + call error (1, MISSING) + } + # If the value is a string, enclose in quotes if + # there are embedded blanks (ignore trailing blanks). + if (datatype[k] < 0) + call inquotes (Memc[lbuf], Memc[lbuf], SZ_LINE, NO) + call fprintf (fd, pformat[1,k]) + call pargstr (Memc[lbuf]) + + # Add width of current column. + line_len = line_len + len_fmt[k] + } + } + call fprintf (fd, "\n") # end of current row + line_len = 0 + } + } + call sfree (sp) +end diff --git a/pkg/utilities/nttools/tprint/tprhtml.x b/pkg/utilities/nttools/tprint/tprhtml.x new file mode 100644 index 00000000..6aecd26a --- /dev/null +++ b/pkg/utilities/nttools/tprint/tprhtml.x @@ -0,0 +1,592 @@ +include <ctype.h> # for IS_WHITE +include <tbset.h> +include "tprint.h" + +define ALIGN_LEFT -1 +define ALIGN_CENTER 0 # currently not used +define ALIGN_RIGHT 1 + +# This file contains subroutines for printing header keywords and/or +# table data in html table format. +# The high-level subroutines are: +# +# tpr_html_begin +# tpr_html_end +# tpr_html_param print header keywords +# tpr_html_pr print table data +# +# Phil Hodge, 9-Aug-1999 Subroutine created + +procedure tpr_html_begin() + +begin + call printf ("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n") + call printf ("<HTML>\n") +end + +procedure tpr_html_end() + +begin + call printf ("</HTML>\n") +end + +# tpr_html_pr -- print contents of table +# This version prints the table data in html format. + +procedure tpr_html_pr (tp, colptr, ncp, s_cp, lgroup, + range_string, pagelength, + showrow, orig_row, showhdr, showunits) + +pointer tp # i: pointer to table descriptor +pointer colptr[ncp] # i: array of pointers to column descriptors +int ncp # i: number of columns to print +pointer s_cp # i: pointer to column to control spacing +int lgroup # i: print blank line after this many lines +char range_string[ARB] # i: string which gives ranges of row numbers +int pagelength # i: number of data lines before printing header +bool showrow # i: true if row number is to be printed +bool orig_row # i: show row number from underlying table? +bool showhdr # i: print column names, etc? +bool showunits # i: print column units? +#-- +pointer sp +pointer buf # for a table entry; also for table info +pointer nelem # array length for each column +pointer align # array of flags for column alignment +int max_nelem # maximum of array lengths +bool has_arrays # true if any column contains arrays +bool has_scalars # true if not all columns contain arrays +char rowspan[SZ_FNAME] # string possibly containing ROWSPAN=max_nelem +int nspan # alternate ROWSPAN=nspan, if extra spacing +int linenum # number of lines of data printed +int tmp_linenum # temporary value for linenum +int line_on_page # number of data lines printed on current page +int nrows # number of rows in table +int rownum # row number +int row # row number to be printed +int cn # loop index for column number +int element # loop index for element within array +int ranges[3,MAX_RANGES] # ranges of row numbers +int nvalues # returned by decode_ranges and ignored +int stat # returned by get_next_number +int s_flag # YES if we should add a line for spacing +int s_nelem # array size of s_cp column, or one +bool done # flag for terminating while loop on rows +int decode_ranges(), get_next_number() +int tbpsta(), tbcigi(), tbagtt() +errchk tbsirow + +begin + call smark (sp) + call salloc (buf, SZ_LINE, TY_CHAR) + call salloc (nelem, ncp, TY_INT) + call salloc (align, ncp, TY_INT) + + # Get info for each column. + max_nelem = 1 # initial values + if (showrow) + has_scalars = true # row number is a scalar + else + has_scalars = false + + if (s_cp == NULL) + s_nelem = 1 + else + s_nelem = tbcigi (s_cp, TBL_COL_LENDATA) + + do cn = 1, ncp { + + # array length + Memi[nelem+cn-1] = tbcigi (colptr[cn], TBL_COL_LENDATA) + if (Memi[nelem+cn-1] > max_nelem) + max_nelem = Memi[nelem+cn-1] + if (Memi[nelem+cn-1] == 1) + has_scalars = true + + # left or right alignment, depending on print format + call tbcigt (colptr[cn], TBL_COL_FMT, Memc[buf], SZ_LINE) + if (Memc[buf+1] == '-') # e.g. %-12s + Memi[align+cn-1] = ALIGN_LEFT + else + Memi[align+cn-1] = ALIGN_RIGHT + } + if (max_nelem > 1) { + has_arrays = true + nspan = max_nelem # initial value + if (lgroup > 1) { + nspan = nspan + max_nelem / (lgroup - 1) + if (max_nelem / (lgroup - 1) * (lgroup - 1) == max_nelem) + nspan = nspan - 1 # one entire line will be blank + } + call sprintf (rowspan, SZ_FNAME, "ROWSPAN=%d") + call pargi (nspan) + } else { + has_arrays = false + rowspan[1] = EOS + } + + call tbtnam (tp, Memc[buf], SZ_LINE) + + call printf ("\n") + call printf ("<HEAD><TITLE>tprint of %s</TITLE></HEAD>\n") + call pargstr (Memc[buf]) + call printf ("<BODY>\n") + call printf ("\n") + + call printf ("<TABLE BORDER=2>\n") + call printf ("<CAPTION ALIGN=TOP>\n") + call printf ("<B>Table data: %s</B>\n") + call pargstr (Memc[buf]) + call printf ("</CAPTION>\n") + call printf ("\n") + + nrows = tbpsta (tp, TBL_NROWS) + + if (showhdr) { + call tpr_h_header (tp, colptr, ncp, showrow, showunits, + Memc[buf], SZ_LINE) + } + + if (decode_ranges (range_string, ranges, MAX_RANGES, nvalues) != OK) + call error (1, "bad range of row numbers") + + # Print each row that is to be printed. + linenum = 0 # initialize line counters + line_on_page = 0 + rownum = 0 # initialize get_next_number + stat = get_next_number (ranges, rownum) # get first row number + done = (stat == EOF) || (rownum > nrows) + + while ( !done ) { + + # If we need to insert extra lines for spacing within a column + # that contains arrays, find out the total number of lines + # we'll need to print. Then set ROWSPAN to this new value. + if (s_nelem > 1) { + # Count the total number of elements we'll span. + nspan = max_nelem # initial value + tmp_linenum = linenum + do element = 1, max_nelem { + call tpr_h_space (tp, s_cp, s_nelem, lgroup, + rownum, element, max_nelem, tmp_linenum, nspan) + tmp_linenum = tmp_linenum + 1 + } + # Overwrite original value of rowspan string. + call sprintf (rowspan, SZ_FNAME, "ROWSPAN=%d") + call pargi (nspan) + } + + # If all columns contain arrays, print a blank line. + if (!has_scalars && rownum > 1) + call tpr_h_blank_line (ncp, showrow) + + # Loop over the number of elements in the longest array. + do element = 1, max_nelem { + + # Check whether we should print a blank line. + # (Set pagelength to zero for this call; in tpr_space, + # blocking into groups of lines is reset at the top of + # each page, but we don't do that with html output.) + call tpr_space (tp, s_cp, lgroup, + rownum, element, max_nelem, 0, linenum, s_flag) + + if (s_flag == YES) { + # Print a blank line. + if (has_arrays && element > 1) { + # Print a blank field for each array column. + call printf (" <TR>\n") + do cn = 1, ncp { + if (Memi[nelem+cn-1] > 1) + call printf (" <TD> </TD>\n") + } + call printf (" </TR>\n") + } else { + call tpr_h_blank_line (ncp, showrow) + } + linenum = linenum + 1 + line_on_page = line_on_page + 1 + } + + # Print column names again, if appropriate. + if (showhdr && element == 1 && pagelength > 0) { + if (line_on_page >= pagelength) { + call tpr_h_header (tp, colptr, ncp, showrow, showunits, + Memc[buf], SZ_LINE) + line_on_page = 0 + } + } + + call printf (" <TR>\n") + + if (element == 1 && showrow) { + if (orig_row) + call tbsirow (tp, rownum, row) + else + row = rownum + if (has_arrays) { + call printf (" <TD ALIGN=RIGHT %s>%d</TD>\n") + call pargstr (rowspan) + call pargi (row) + } else { + call printf (" <TD ALIGN=RIGHT>%d</TD>\n") + call pargi (row) + } + } + + # Print each column. + do cn = 1, ncp { + + # Does the current column contain arrays? + if (Memi[nelem+cn-1] > 1) { + + if (element <= Memi[nelem+cn-1]) { + if (tbagtt (tp, colptr[cn], rownum, + Memc[buf], SZ_LINE, element, 1) < 1) + call error (1, "can't read array element") + call tpr_cell (Memc[buf], Memi[align+cn-1], + false, "") + } else { + call printf (" <TD> </TD>\n") + } + + } else if (element == 1) { + + call tbegtt (tp, colptr[cn], rownum, + Memc[buf], SZ_LINE) + if (has_arrays) { + call tpr_cell (Memc[buf], Memi[align+cn-1], + true, rowspan) + } else { + call tpr_cell (Memc[buf], Memi[align+cn-1], + false, "") + } + } + } + + call printf (" </TR>\n") + linenum = linenum + 1 + line_on_page = line_on_page + 1 + } + + stat = get_next_number (ranges, rownum) + done = (stat == EOF) || (rownum > nrows) + } + + # Print column names at the end of the document, if appropriate. + if (showhdr && pagelength > 0) { + if (line_on_page >= pagelength) { + call tpr_h_header (tp, colptr, ncp, showrow, showunits, + Memc[buf], SZ_LINE) + } + } + + call printf ("</TABLE>\n") + call printf ("</BODY>\n") + call flush (STDOUT) + + call sfree (sp) +end + +procedure tpr_h_blank_line (ncp, showrow) + +int ncp # i: number of columns to print +bool showrow # i: true if we also print row numbers +#-- +int nspan # number of columns to span + +begin + if (showrow) + nspan = ncp + 1 + else + nspan = ncp + + call printf (" <TR>\n") + call printf (" <TD COLSPAN=%d> </TD>\n") + call pargi (nspan) + call printf (" </TR>\n") +end + +# This is a simplified version of tpr_space which just increments the count +# of the number of elements to be spanned in a ROWSPAN tag. +# +# We can't just call tpr_space to do this, because each time it examines +# a row, it saves the current value as 'previous'. We need this routine +# in order to have a separate 'previous' variable. +# +# We don't need to increment linenum if nspan is incremented, because we +# only use this routine for spacing in arrays, and it's the element number +# that we care about for that case. + +procedure tpr_h_space (tp, s_cp, s_nelem, lgroup, + rownum, element, max_nelem, linenum, nspan) + +pointer tp # i: pointer to table descriptor +pointer s_cp # i: pointer to column to control spacing +int s_nelem # i: array size of s_cp column +int lgroup # i: print blank after this many lines +int rownum # i: number of current row +int element # i: array element number +int max_nelem # i: max value for element +int linenum # i: number of lines that have been printed +int nspan # io: incremented if we should increment ROWSPAN +#-- +pointer sp +pointer current # scratch for value of column in current row +int lpage # number of line we would print +int s_flag # YES if we would print a line for spacing +char previous[SZ_LINE] # value of column in previous row +bool do_compare # true if we should compare column values +bool strne() +int junk, tbagtt() +errchk tbegtt, tbagtt + +begin + s_flag = NO # may be changed later + + # linenum is the number of lines that have already been printed. + # lpage is the current line number. + lpage = linenum + 1 + + # If this is the first line, get the current value of the column + # and save it as "previous". That's all. + if (lpage == 1) { + junk = tbagtt (tp, s_cp, rownum, previous, SZ_LINE, element, 1) + return + } + + # Have we printed a group of lines? If so, set the flag to indicate + # that we should print a blank line. + if (lgroup > 1) { + if (max_nelem > 1) { + if (lpage > 1) { + if (lgroup == 2) + s_flag = YES + else if (mod (element, lgroup-1) == 1) + s_flag = YES + } + } else if (mod (lpage, lgroup) == 0) { + s_flag = YES + } + } + + # Check the value in the column. + if (element <= s_nelem) { + if (s_flag == YES) { + # Since we already know we need to print a space, we don't + # have to compare current and previous values, but we still + # must save current value as "previous". + junk = tbagtt (tp, s_cp, rownum, previous, SZ_LINE, + element, 1) + } else { + # Get current value, and compare it with previous value. + call smark (sp) + call salloc (current, SZ_LINE, TY_CHAR) + do_compare = true # may be reset + junk = tbagtt (tp, s_cp, rownum, Memc[current], SZ_LINE, + element, 1) + if (do_compare && strne (Memc[current], previous)) { + # Set flag; save current value as previous value. + s_flag = YES + call strcpy (Memc[current], previous, SZ_LINE) + } + call sfree (sp) + } + } + + # If we should print a line before the first element of an array, + # we'll print a full line, rather than adding one to ROWSPAN; this + # is why we include the test on element. + if (s_flag == YES && element > 1) + nspan = nspan + 1 +end + +# This routine trims trailing blanks from the input buffer (in-place), +# and it sets ip to the index of the first non-blank character. If +# the entire field is blank, the string " " is assigned to the +# input buffer. + +procedure tpr_deblank (buf, ip) + +char buf[ARB] # io: input string (trailing blanks will be truncted) +int ip # o: first non-blank character in buf +#-- +int strlen() + +begin + ip = strlen (buf) + while (ip >= 1 && IS_WHITE(buf[ip])) { # trim trailing blanks + buf[ip] = EOS + ip = ip - 1 + } + ip = 1 + while (IS_WHITE(buf[ip])) # trim leading blanks + ip = ip + 1 + if (buf[ip] == EOS) { + call strcpy (" ", buf, SZ_LINE) + ip = 1 + } +end + +# This routine prints one table element. + +procedure tpr_cell (buf, align, print_rowspan, rowspan) + +char buf[ARB] # io: input string (trailing blanks will be truncted) +int align # i: ALIGN_LEFT or ALIGN_RIGHT +bool print_rowspan # i: true --> print rowspan string +char rowspan[ARB] # i: ROWSPAN=<n> +#-- +int ip # first non-blank character in buf + +begin + call tpr_deblank (buf, ip) + + if (print_rowspan) { + + if (align == ALIGN_LEFT) { + call printf (" <TD ALIGN=LEFT %s>%s</TD>\n") + call pargstr (rowspan) + call pargstr (buf[ip]) + } else { + call printf (" <TD ALIGN=RIGHT %s>%s</TD>\n") + call pargstr (rowspan) + call pargstr (buf[ip]) + } + + } else { + + if (align == ALIGN_LEFT) { + call printf (" <TD ALIGN=LEFT>%s</TD>\n") + call pargstr (buf[ip]) + } else { + call printf (" <TD ALIGN=RIGHT>%s</TD>\n") + call pargstr (buf[ip]) + } + } +end + +procedure tpr_h_header (tp, colptr, ncp, showrow, showunits, buf, maxch) + +pointer tp # i: pointer to table descriptor +pointer colptr[ncp] # i: array of pointers to column descriptors +int ncp # i: number of columns to print +bool showrow # i: true if row number is to be printed +bool showunits # i: print column units? +char buf[ARB] # o: scratch space +int maxch # i: size of buf +#-- +int cn # loop index for column number + +begin + call printf (" <TR>\n") + + if (showrow) + call printf (" <TH ALIGN=RIGHT>(row)</TH>\n") + + do cn = 1, ncp { + call tbcigt (colptr[cn], TBL_COL_NAME, buf, SZ_LINE) + call printf (" <TH>%s</TH>\n") + call pargstr (buf) + } + call printf (" </TR>\n") + + if (showunits) { + call printf (" <TR>\n") + if (showrow) + call printf (" <TH> </TH>\n") + do cn = 1, ncp { + call tbcigt (colptr[cn], TBL_COL_UNITS, buf, SZ_LINE) + if (buf[1] == EOS) { + call printf (" <TH> </TH>\n") + } else { + call printf (" <TH>%s</TH>\n") + call pargstr (buf) + } + } + call printf (" </TR>\n") + } +end + +# This routine prints all the header keywords for a table. + +procedure tpr_html_param (tp) + +pointer tp # i: pointer to table descriptor +#-- +pointer sp +pointer buf # for a keyword value +pointer comment # keyword comment +int npar # number of header parameters +char keyword[SZ_KEYWORD] # keyword name +int n # loop index for keyword number +int dtype # returned by tbhgnp and ignored +int tbpsta() + +begin + npar = tbpsta (tp, TBL_NPAR) + if (npar <= 0) + return + + call smark (sp) + call salloc (buf, SZ_FNAME, TY_CHAR) + call salloc (comment, SZ_FNAME, TY_CHAR) + + call tbtnam (tp, Memc[buf], SZ_LINE) + + call printf ("\n") + call printf ("<HEAD><TITLE>tprint of %s</TITLE></HEAD>\n") + call pargstr (Memc[buf]) + call printf ("<BODY>\n") + call printf ("\n") + + call printf ("<TABLE BORDER=2>\n") + call printf ("<CAPTION ALIGN=TOP>\n") + call printf ("<B>Table keywords: %s</B>\n") + call pargstr (Memc[buf]) + call printf ("</CAPTION>\n") + call printf ("\n") + + call printf (" <TR>\n") + call printf (" <TH>keyword</TH>\n") + call printf (" <TH>value</TH>\n") + call printf (" <TH>comment</TH>\n") + call printf (" </TR>\n") + + do n = 1, npar { + + call printf (" <TR>\n") + + # Get the Nth header parameter and comment. + call tbhgnp (tp, n, keyword, dtype, Memc[buf]) + call tbhgcm (tp, keyword, Memc[comment], SZ_FNAME) + + if (keyword[1] == EOS) { + call printf (" <TD> </TD>\n") + } else { + call printf (" <TD>%s</TD>\n") + call pargstr (keyword) + } + + if (Memc[buf] == EOS) { + call printf (" <TD> </TD>\n") + } else { + call printf (" <TD>%s</TD>\n") + call pargstr (Memc[buf]) + } + + if (Memc[comment] == EOS) { + call printf (" <TD> </TD>\n") + } else { + call printf (" <TD>%s</TD>\n") + call pargstr (Memc[comment]) + } + + call printf (" </TR>\n") + } + + call printf ("</TABLE>\n") + call printf ("</BODY>\n") + call flush (STDOUT) + + call sfree (sp) +end diff --git a/pkg/utilities/nttools/tprint/tprint.h b/pkg/utilities/nttools/tprint/tprint.h new file mode 100644 index 00000000..d0781b1c --- /dev/null +++ b/pkg/utilities/nttools/tprint/tprint.h @@ -0,0 +1,5 @@ +define MAXCOLS 52 # maximum number of columns per page +define SZ_FMT 17 # size of string containing print format +define MAX_RANGES (SZ_LINE/2) # max number of ranges of row numbers +define SHORT_STRING 11 # size of short text strings +define SZ_ROW_HDR 5 # size of header for row number: "# row" diff --git a/pkg/utilities/nttools/tprint/tprint.x b/pkg/utilities/nttools/tprint/tprint.x new file mode 100644 index 00000000..65c2d09d --- /dev/null +++ b/pkg/utilities/nttools/tprint/tprint.x @@ -0,0 +1,535 @@ +include <time.h> # defines SZ_TIME for datestr +include <error.h> # defines EA_WARN +include <finfo.h> # used by tpr_fm_date +include <fset.h> # used to check whether output is redirected +include <tbset.h> +include "tprint.h" + +# tprint -- Program to print tables. +# +# Phil Hodge, 31-Jul-1987 Task created +# Phil Hodge, 11-Aug-1987 Delete call to tbtext. +# Phil Hodge, 28-Aug-1987 Write date that table was last modified. +# Phil Hodge, 12-Oct-1987 Include LaTeX/TeX option. +# Phil Hodge, 30-Dec-1987 Filename template; tctexp for column names. +# Phil Hodge, 12-Feb-1988 Include option to align columns if format is small. +# Phil Hodge, 30-Mar-1988 Page width = ttyncols; get sp_col & lgroup. +# Phil Hodge, 7-Sep-1988 Change parameter name for table. +# Phil Hodge, 10-May-1991 Use clpopns instead of clpopnu. +# Phil Hodge, 26-Mar-1992 Remove call to tbtext; use tbtnam instead. +# Phil Hodge, 28-Oct-1992 Set align=false if showhdr=false. +# Phil Hodge, 5-Jul-1993 Include option to print column units. +# Phil Hodge, 3-Feb-1994 Set showunits to false for a text table. +# Phil Hodge, 15-Dec-1994 Increase size of table name from SZ_FNAME to SZ_LINE. +# Phil Hodge, 16-Feb-1995 In tpr_param_pr, print "#" before header lines. +# Phil Hodge, 6-Mar-1995 In tpr_param_pr, print comment for header parameter. +# Phil Hodge, 23-Jun-1995 In tpr_fm_date, get file name using tbparse. +# Phil Hodge, 3-Oct-1995 Replace clgfil calls with tbn... . +# Phil Hodge, 9-Apr-1996 Error check tbtopn and tpr_data_pr; +# call error if number of columns to print is zero (i.e. if no +# column was found); flush STDOUT. +# Phil Hodge, 5-Jun-1997 Use single instead of double quotes for keyword +# text value, if there's an associated comment. +# Phil Hodge, 26-Mar-1998 Add orig_row to par file, to show row number in +# underlying table in case a row selector was used. +# Phil Hodge, 7-Jun-1999 Allow showunits to be true for a text table; +# this overrides the change made on 3-Feb-1994; +# if input is redirected, set input to STDIN without getting cl param. +# Phil Hodge, 9-Aug-1999 Add option = html; modify tpr_space to handle +# arrays and to just set a flag, rather than actually printing the space. +# Phil Hodge, 3-Jul-2000 In tpr_param_pr, delete leading blanks from the +# value and comment. +# Phil Hodge, 15-Jul-2009 In tpr_fm_date, remove ttype from the call to +# tbparse. + +procedure tprint() + +pointer tp # pointer to input table descr +pointer sp # stack pointer +pointer tname # scratch for table name +pointer columns # scratch for list of column names +pointer range_string # string which gives ranges of row numbers +pointer tlist # for list of input table names +int pagewidth # max number of char in line length +int pagelength # number of data lines (excl header) per page +int lgroup # number of lines to group together on output +bool prparam, prdata # print header parameters? data? +bool showrow # show row number on output? +bool orig_row # show row number from underlying table? +bool showhdr # show table name, column names, etc on output? +bool showunits # show column units on output? +bool align # override print fmt to align col & name? +char prt_option[SHORT_STRING] # "plain", "latex", "tex" +char sp_cname[SZ_COLNAME] # name of column to control spacing +bool first_table # false ==> print line to separate tables +int clgeti(), fstati(), envgeti() +bool clgetb() +pointer tbnopenp(), tbnopen() +int tbnget() +pointer tbtopn() + +begin + call smark (sp) + call salloc (tname, SZ_LINE, TY_CHAR) + call salloc (columns, SZ_LINE, TY_CHAR) + + if (fstati (STDIN, F_REDIR) == YES) + tlist = tbnopen ("STDIN") + else + tlist = tbnopenp ("table") + + # Find out which portions of the table the user wants to print. + prparam = clgetb ("prparam") + prdata = clgetb ("prdata") + if (!prparam && !prdata) { + call sfree (sp) + return + } + + if (prdata) { + # Get parameters relevant to printing data portion of table. + + call salloc (range_string, SZ_LINE, TY_CHAR) + + # Get page width from ttyncols unless output is redirected. + if (fstati (STDOUT, F_REDIR) == YES) + pagewidth = clgeti ("pwidth") + else + pagewidth = envgeti ("ttyncols") + pagelength = clgeti ("plength") + showrow = clgetb ("showrow") + orig_row = clgetb ("orig_row") + call clgstr ("columns", Memc[columns], SZ_LINE) + call clgstr ("rows", Memc[range_string], SZ_LINE) + align = clgetb ("align") + + call clgstr ("sp_col", sp_cname, SZ_COLNAME) + lgroup = clgeti ("lgroup") + 1 # add one for the space + } + + call clgstr ("option", prt_option, SHORT_STRING) + showhdr = clgetb ("showhdr") + if (showhdr) { + showunits = clgetb ("showunits") + } else { + # There's no need to align columns with their names if the names + # are not printed. + align = false + showunits = false + } + + if (prt_option[1] == 'h') # HTML + call tpr_html_begin() + + # Loop over all table names in the file name template. + first_table = true + while (tbnget (tlist, Memc[tname], SZ_LINE) != EOF) { + + if ( ! first_table ) { + call printf ("\n") # blank line between tables + call flush (STDOUT) + } + first_table = false + + # Open the table. + iferr { + tp = tbtopn (Memc[tname], READ_ONLY, 0) + } then { + call erract (EA_WARN) + next + } + + # Get the full table name (for use by tpr_fm_date), + call tbtnam (tp, Memc[tname], SZ_LINE) + + # Print the name of the table and the date that the table was + # last modified. + if (showhdr) + call tpr_fm_date (Memc[tname], prt_option) + + if (prparam) # print header parameters + call tpr_param_pr (tp, prt_option, prdata) + + if (prdata) { # print data portion of table + iferr { + call tpr_data_pr (tp, pagewidth, pagelength, + showrow, orig_row, showhdr, showunits, + align, sp_cname, lgroup, + Memc[columns], Memc[range_string], prt_option) + } then { + call tbtclo (tp) + call erract (EA_WARN) + next + } + } + + call tbtclo (tp) + } + if (prt_option[1] == 'h') # HTML + call tpr_html_end() + + call tbnclose (tlist) + call sfree (sp) +end + + + +# tpr_fm_date -- Get date of file +# This procedure gets the date that a table was last modified and writes +# the table name and date to STDOUT. + +procedure tpr_fm_date (tablename, prt_option) + +char tablename[ARB] # i: name of table +char prt_option[ARB] # i: "plain", "latex", or "tex" +#-- +pointer sp +pointer filename # name of table without brackets +pointer cdfname # returned by tbparse and ignored +int hdu # ignored +long ostruct[LEN_FINFO] # contains info about file +long mtime +char datestr[SZ_TIME] # date that table was last modified +char percent # the % character +int junk, tbparse() +int finfo() + +begin + if (prt_option[1] == 'h') # HTML + return + + call smark (sp) + call salloc (filename, SZ_FNAME, TY_CHAR) + call salloc (cdfname, SZ_FNAME, TY_CHAR) + + # Get file name from table name. + junk = tbparse (tablename, Memc[filename], + Memc[cdfname], SZ_FNAME, hdu) + + percent = '%' + + if (finfo (Memc[filename], ostruct) != ERR) { + mtime = FI_MTIME(ostruct) + call cnvtime (mtime, datestr, SZ_TIME) + + if (prt_option[1] == 'p') { # plain print + call printf ("# Table %s %s\n") + call pargstr (tablename) + call pargstr (datestr) + } else { # LaTeX or TeX + call printf ("%c") + call pargc (percent) # comment + call printf (" Table %s %s\n") + call pargstr (tablename) + call pargstr (datestr) + } + call printf ("\n") + } + call flush (STDOUT) + + call sfree (sp) +end + + + +# tpr_param_pr -- Print header parameters +# This procedure prints the header parameters on STDOUT. +# +# Phil Hodge, 5-Oct-1987 Subroutine created +# Phil Hodge, 30-Dec-1987 If latex or tex, print % prefix. +# Phil hodge, 9-Mar-1989 Change type of dtype in tbhgnp from char to int. + +procedure tpr_param_pr (tp, prt_option, prdata) + +pointer tp # i: pointer to table descriptor +char prt_option[ARB] # i: "plain", "latex", or "tex" +bool prdata # i: print data? (not here, though) +#-- +pointer sp +pointer value # scratch for value of parameter (string) +pointer comment # scratch for comment for parameter +int dtype # data type (TY_CHAR, etc) +int npar # number of header parameters +int n # loop index for parameter number +int ipp, ipc # offsets for skipping leading blanks +char keyword[SZ_KEYWORD] # buffer for header parameter keyword +char percent # the % character +int tbpsta() + +begin + if (prt_option[1] == 'h') { # HTML + call tpr_html_param (tp) + return + } + + percent = '%' + npar = tbpsta (tp, TBL_NPAR) + if (npar > 0) { + call smark (sp) + call salloc (value, SZ_PARREC, TY_CHAR) + call salloc (comment, SZ_PARREC, TY_CHAR) + do n = 1, npar { + + # Get the Nth header parameter and comment. + call tbhgnp (tp, n, keyword, dtype, Memc[value]) + call tbhgcm (tp, keyword, Memc[comment], SZ_PARREC) + ipp = 0 + while (Memc[value+ipp] == ' ') + ipp = ipp + 1 + ipc = 0 + while (Memc[comment+ipc] == ' ') + ipc = ipc + 1 + + if (prt_option[1] != 'p') { # LaTeX or TeX, not plain + call printf ("%c") + call pargc (percent) # comment + } else if (prdata) { # plain output, with data + call printf ("#K ") # comment + } + + # Print the keyword and value, and possibly a comment. + if (Memc[comment+ipc] == EOS) { # no comment to print + + call printf ("%-8s %s\n") + call pargstr (keyword) + call pargstr (Memc[value+ipp]) + + } else if (dtype == TY_CHAR) { + + # Enclose value in quotes to distinguish from comment. + call printf ("%-8s '%s' %s\n") + call pargstr (keyword) + call pargstr (Memc[value+ipp]) + call pargstr (Memc[comment+ipc]) + + } else { + + # Numeric; no quotes needed. + call printf ("%-8s %s %s\n") + call pargstr (keyword) + call pargstr (Memc[value+ipp]) + call pargstr (Memc[comment+ipc]) + } + } + call sfree (sp) + call printf ("\n") + } + call flush (STDOUT) +end + + + +# tpr_data_pr -- Print table data +# This procedure prints the data portion of a table on STDOUT. +# +# Phil Hodge, 5-Oct-1987 Subroutine created +# Phil Hodge, 12-Feb-1988 Include option to align columns if format is small. +# Phil Hodge, 30-Mar-1988 Get column to control spacing of printout. + +procedure tpr_data_pr (tp, pagewidth, pagelength, + showrow, orig_row, showhdr, showunits, + align, sp_cname, lgroup, + columns, range_string, prt_option) + +pointer tp # i: pointer to table descriptor +int pagewidth # i: page width +int pagelength # i: number of lines of table per page +bool showrow # i: print row number? +bool orig_row # i: show row number from underlying table? +bool showhdr # i: print column names, etc? +bool showunits # i: print column units? +bool align # i: override print fmt to align col & name? +char sp_cname[SZ_COLNAME] # i: column to control spacing +int lgroup # i: print blank line after this many lines +char columns[ARB] # i: list of names of columns to be printed +char range_string[ARB] # i: range of row numbers to print +char prt_option[ARB] # i: "plain", "latex", or "tex" +#-- +pointer sp +pointer cptr # scratch for array of column pointers +pointer s_cp # pointer to column to control spacing +int nrows, ncols # number of rows and columns in table +int ncp # number of columns to print (may be < ncols) +int k # loop index +int tbpsta() + +begin + nrows = tbpsta (tp, TBL_NROWS) + ncols = tbpsta (tp, TBL_NCOLS) + + if ((nrows < 1) || (ncols < 1)) { + call eprintf ("table is empty\n") + return # nothing more to do + } + + # Allocate enough space for storing a descriptor for each column. + call smark (sp) + call salloc (cptr, ncols, TY_POINTER) + + # Get column pointers for all columns that are to be printed. + call tctexp (tp, columns, ncols, ncp, Memi[cptr]) + + # Check whether there is a column to control spacing. + k = 1 + while ((sp_cname[k] == ' ' || sp_cname[k] == '\t') && + (sp_cname[k] != EOS) && (k <= SZ_COLNAME)) + k = k + 1 + if (sp_cname[k] != EOS) { + call tbcfnd1 (tp, sp_cname[k], s_cp) + if (s_cp == NULL) { + call eprintf ("WARNING: column `%s' for spacing not found\n") + call pargstr (sp_cname) + } + } else { + s_cp = NULL + } + + if (ncp > 0) { + # Print the values in the table. + if (prt_option[1] == 'p') { # plain printing + call tpr_plain_pr (tp, Memi[cptr], ncp, s_cp, lgroup, + range_string, pagewidth, pagelength, + showrow, orig_row, showhdr, showunits, align) + } else if (prt_option[1] == 'h') { # html table + call tpr_html_pr (tp, Memi[cptr], ncp, s_cp, lgroup, + range_string, pagelength, + showrow, orig_row, showhdr, showunits) + } else { # LaTeX or TeX + call tpr_latex_pr (tp, Memi[cptr], ncp, s_cp, lgroup, + range_string, pagewidth, pagelength, + showrow, orig_row, showhdr, showunits, prt_option) + } + call flush (STDOUT) + } else { + call error (1, "column not found") + } + call sfree (sp) +end + + + +# tpr_space -- print line separator +# Check whether we should print a blank line (or other line separator) if +# the value in the designated column has changed since the last call to +# this routine or if a group of lgroup lines has been printed. +# The groups of lines are counted starting at the beginning of each +# page; this makes a difference if lgroup does not divide pagelength. +# If any column being printed contains arrays, then lgroup is applied +# to element number, not to line number. +# +# If lgroup is one then it will be ignored; if s_cp is NULL then +# the column values will be ignored. +# When linenum is zero, the "previous" column value is initialized +# with the current value. + +procedure tpr_space (tp, s_cp, lgroup, + rownum, element, max_nelem, pagelength, linenum, s_flag) + +pointer tp # i: pointer to table descriptor +pointer s_cp # i: pointer to column to control spacing +int lgroup # i: print blank after this many lines +int rownum # i: number of current row +int element # i: array element number +int max_nelem # i: max value for element +int pagelength # i: number of data lines per page +int linenum # i: number of lines that have been printed +int s_flag # o: YES if we should print a line for spacing +#-- +pointer sp +pointer current # scratch for value of column in current row +int lpage # number of lines already printed on this page +char previous[SZ_LINE] # value of column in previous row +bool do_compare # true if we should compare column values +bool strne() +int nelem, tbcigi(), junk, tbagtt() +errchk tbegtt, tbagtt + +begin + s_flag = NO # may be changed later + + if (lgroup <= 1 && s_cp == NULL) + return + + if (pagelength > 0) + lpage = mod (linenum, pagelength) + 1 + else + lpage = linenum + 1 + + if (s_cp != NULL) + nelem = tbcigi (s_cp, TBL_COL_LENDATA) + else + nelem = 1 + + # If we're at the beginning of a page, get the current value + # of the column and save it as "previous". That's all. + if (lpage == 1) { + if (s_cp != NULL) { + if (nelem > 1) { + if (element <= nelem) { + junk = tbagtt (tp, s_cp, rownum, previous, SZ_LINE, + element, 1) + } + } else { + call tbegtt (tp, s_cp, rownum, previous, SZ_LINE) + } + } + return + } + + # Have we printed a group of lines? If so, set the flag to indicate + # that we should print a blank line. + # If we're printing arrays, apply lgroup to the array elements instead + # of to the rows, but in this case also print a space between each row + # (i.e. when element is one), except at the top of a page. + # Note: The value of lgroup is one more than the parameter value, + # so that it can be used with mod on linenum, because linenum gets + # incremented when a blank line is printed. But here we want to use + # lgroup with element, which doesn't get incremented. That's why + # we subtract one from lgroup in "mod (element, lgroup-1)". + if (lgroup > 1) { + if (max_nelem > 1) { + if (lpage > 1) { + if (lgroup == 2) + s_flag = YES + else if (mod (element, lgroup-1) == 1) + s_flag = YES + } + } else if (mod (lpage, lgroup) == 0) { + s_flag = YES + } + } + + # Check the value in the column. + if (s_cp != NULL) { + if (s_flag == YES) { + # If we already know we need to print a space, we don't have + # to compare current and previous values, but we still must + # save current value as "previous". + if (nelem > 1 && element <= nelem) { + junk = tbagtt (tp, s_cp, rownum, previous, SZ_LINE, + element, 1) + } else if (element == 1) { + call tbegtt (tp, s_cp, rownum, previous, SZ_LINE) + } # else we already have the value + } else { + # Get current value, and compare it with previous value. + call smark (sp) + call salloc (current, SZ_LINE, TY_CHAR) + do_compare = true # may be reset + if (nelem > 1 && element <= nelem) { + junk = tbagtt (tp, s_cp, rownum, Memc[current], SZ_LINE, + element, 1) + } else if (element == 1) { + call tbegtt (tp, s_cp, rownum, Memc[current], SZ_LINE) + } else { + do_compare = false + } + if (do_compare && strne (Memc[current], previous)) { + # Set flag; save current value as previous value. + s_flag = YES + call strcpy (Memc[current], previous, SZ_LINE) + } + call sfree (sp) + } + } +end diff --git a/pkg/utilities/nttools/tprint/tprlatex.x b/pkg/utilities/nttools/tprint/tprlatex.x new file mode 100644 index 00000000..2875caa8 --- /dev/null +++ b/pkg/utilities/nttools/tprint/tprlatex.x @@ -0,0 +1,579 @@ +include <tbset.h> +include "tprint.h" + +# tpr_latex_pr -- print contents of table +# This version prints the table data in a form suitable for input to +# TeX or LaTeX. The corresponding procedure that prints in plain text +# format is tpr_plain_pr. +# +# Phil Hodge, 7-Oct-1987 Subroutine created +# Phil Hodge, 12-Feb-1988 Call tpr_pfmt_l instead of tpr_pfmt +# Phil Hodge, 30-Mar-1988 Use a column to control spacing of printout. +# Phil Hodge, 6-Jan-1989 tpr_break_l for new page, also after tpr_cnames_pr. +# Phil Hodge, 2-Apr-1993 In prt_row_l, include short datatype. +# Phil Hodge, 5-Jul-1993 Include option to print column units. +# Phil Hodge, 26-Mar-1998 Add orig_row to calling sequence, use in prt_row_l; +# in tpr_break_l, the calling sequence of tpr_end_tbl +# had an extra argument. +# Phil Hodge, 9-Aug-1999 Change the calling sequence of tpr_space. + +procedure tpr_latex_pr (tp, colptr, ncp, s_cp, lgroup, + range_string, pagewidth, pagelength, + showrow, orig_row, showhdr, showunits, prt_option) + +pointer tp # i: pointer to table descriptor +pointer colptr[ncp] # i: array of pointers to column descriptors +int ncp # i: number of columns to print +pointer s_cp # i: pointer to column to control spacing +int lgroup # i: print a blank line after this many lines +char range_string[ARB] # i: string which gives ranges of row numbers +int pagewidth # i: page width +int pagelength # i: number of data lines per page +bool showrow # i: true if row number is to be printed +bool orig_row # i: show row number from underlying table? +bool showhdr # i: print column names, etc? +bool showunits # i: print column units? +char prt_option[ARB] # i: "latex" or "tex" +#-- +pointer sp +pointer data_fmt # print formats for column data values +pointer j_flag # left or right justification +char rn_fmt[SZ_FMT] # format for printing row numbers +char rn_name[SZ_ROW_HDR] # row number header: "(row)" +char percent # a percent sign (comment for TeX) +int nrows # total number of rows in table +int element # loop index for array element number +int max_nelem # max number of elements +int rn_width # width needed for printing row number +int lenfmt[MAXCOLS] # lengths of print fmt for cols on current page +int rownum # row number +int linenum # number of lines of data printed +int ranges[3,MAX_RANGES] # ranges of row numbers +int nvalues # returned by decode_ranges and ignored +int stat # returned by get_next_number +int k # loop index +int s_flag # YES if we should add a line for spacing +bool done # flag for terminating while loop on rows +int decode_ranges(), get_next_number(), tbpsta(), tbcigi() + +begin + percent = '%' + + # Allocate space for format strings for printing column names + # and values. + call smark (sp) + call salloc (data_fmt, (SZ_FMT+1)*ncp, TY_CHAR) + call salloc (j_flag, ncp, TY_INT) + + if (ncp > MAXCOLS) { + call eprintf ("maximum number of columns is %d\n") + call pargi (MAXCOLS) + call error (1, "") + } + + nrows = tbpsta (tp, TBL_NROWS) + + if (decode_ranges (range_string, ranges, MAX_RANGES, nvalues) != OK) + call error (1, "bad range of row numbers") + + # These three values (rn_name, rn_fmt, rn_width) must be consistent. + call strcpy ("(row)", rn_name, SHORT_STRING) + call strcpy ("%5d", rn_fmt, SZ_FMT) + if (showrow) + rn_width = SZ_ROW_HDR # space for printing row number + else + rn_width = 0 + + # Get length of print format for each column. + do k = 1, ncp + lenfmt[k] = tbcigi (colptr[k], TBL_COL_FMTLEN) + + # Fill array of print formats for column names and for data. + call tpr_pfmt_l (colptr, lenfmt, Memc[data_fmt], + Memi[j_flag], ncp) + + if (showhdr) { + # Print the \begin{document} string. + call tpr_beg_doc (prt_option) + + # Print the default \def or \newcommand for column separators + # and \eol, and print the begin-table string and column names. + call tpr_def (prt_option, ncp, showrow) + call tpr_begin_tbl (prt_option, Memi[j_flag], ncp, showrow) + call tpr_cnames_pr_l (colptr, ncp, showrow, showunits, rn_name) + } + + # Print each row that is to be printed. + linenum = 0 # initialize line counter + rownum = 0 # initialize get_next_number + stat = get_next_number (ranges, rownum) # get first row number + done = (stat == EOF) || (rownum > nrows) + + element = 1 # not used yet + max_nelem = 1 + + while ( !done ) { + + # Print a page break if appropriate. + call tpr_break_l (linenum, pagelength, showhdr, showunits, + prt_option, Memi[j_flag], + colptr, ncp, showrow, rn_name) + + # Print a blank line if the column value has changed or if + # a group of lgroup lines have been printed. + call tpr_space (tp, s_cp, lgroup, + rownum, element, max_nelem, pagelength, linenum, s_flag) + if (s_flag == YES) { + call printf ("\\extline\n") + linenum = linenum + 1 + # Check whether we should also print a page break. + call tpr_break_l (linenum, pagelength, showhdr, showunits, + prt_option, Memi[j_flag], + colptr, ncp, showrow, rn_name) + } + + # Print % as row separator (for readability); print current row. + call printf ("%c\n") + call pargc (percent) + call prt_row_l (tp, colptr, Memc[data_fmt], ncp, rownum, + lenfmt, pagewidth, showrow, orig_row, rn_fmt, rn_width) + linenum = linenum + 1 + stat = get_next_number (ranges, rownum) + done = (stat == EOF) || (rownum > nrows) + } + + if (showhdr) { + # Print end-table string. + call tpr_end_tbl (prt_option) + } + if (showhdr) + # Write \end{document} string. + call tpr_end_doc (prt_option) + + call sfree (sp) +end + +# tpr_break_l -- print a page break +# This routine prints the "end table" and "begin table" strings, if +# appropriate. If pagelength is zero we're not printing page breaks +# anyway, and if linenum is zero we've already printed the header, so +# nothing is done. Otherwise, if linenum is zero mod pagelength +# print a page break, and if showhdr print the column names. + +procedure tpr_break_l (linenum, pagelength, showhdr, showunits, + prt_option, just_flag, + colptr, ncp, showrow, rn_name) + +int linenum # io: number of lines of data printed +int pagelength # i: number of data lines per page +bool showhdr # i: print column names? +bool showunits # i: print column units? +char prt_option[ARB] # i: "latex" or "tex" +int just_flag[ARB] # i: -1, 0, +1 for left, center, right just. +pointer colptr[ARB] # i: array of column pointers +int ncp # i: number of columns to print +bool showrow # i: print row number? +char rn_name[ARB] # i: column header for row number +#-- + +begin + if (pagelength > 0) { + if (linenum > 0) { + if (mod (linenum, pagelength) == 0) { + # Print end table, begin table, and column names. + call tpr_end_tbl (prt_option) + call tpr_begin_tbl (prt_option, just_flag, ncp, + showrow) + if (showhdr) + call tpr_cnames_pr_l (colptr, ncp, + showrow, showunits, rn_name) + } + } + } +end + + +# tpr_pfmt_l -- Get print formats +# This procedure fills an array with print formats for printing the +# column values. An array of flags specifying whether each column is +# to be left or right justified is also returned. + +procedure tpr_pfmt_l (colptr, lenfmt, data_fmt, just_flag, ncp) + +pointer colptr[ncp] # i: array of column pointers +int lenfmt[ncp] # i: array of lengths of print formats +char data_fmt[SZ_FMT,ncp] # o: array of print formats for data +int just_flag[ncp] # o: -1 or +1 for left, right justification +int ncp # i: number of columns to print +#-- +int cn # loop index for column number + +begin + do cn = 1, ncp { # do for each column to print + + call tbcigt (colptr[cn], TBL_COL_FMT, data_fmt[1,cn], SZ_FMT) + if (data_fmt[2,cn] == '-') + just_flag[cn] = -1 # left justification + else + just_flag[cn] = 1 # right justification + } +end + + + +# tpr_beg_doc -- Print begin-document strings +# This procedure prints strings for LaTeX or for TeX that begin +# a document. (Nothing is written for TeX.) + +procedure tpr_beg_doc (prt_option) + +char prt_option[ARB] # i: "latex" or "tex" + +begin + if (prt_option[1] == 'l') { # LaTeX + call printf ("\\documentstyle{article}\n") + call printf ("\\begin{document}\n") + } +end + + + +# tpr_end_doc -- Print end-document strings +# This procedure prints strings for LaTeX or for TeX that end +# a document. + +procedure tpr_end_doc (prt_option) + +char prt_option[ARB] # i: "latex" or "tex" + +begin + if (prt_option[1] == 'l') # LaTeX + call printf ("\\end{document}\n") + else if (prt_option[1] == 't') # TeX + call printf ("\\end\n") +end + + +# tpr_def -- Print newcommand strings +# This procedure prints strings for LaTeX or for TeX that define +# macros for column separators and for the end-of-line string. +# +# Phil Hodge, 1-Apr-88 \extline added + +procedure tpr_def (prt_option, ncp, showrow) + +char prt_option[ARB] # i: "latex" or "tex" +int ncp # i: number of columns to print +bool showrow # i: print row number? +#-- +int k # loop index +char new_cmd[SHORT_STRING] # "\newcommand" or "\def" +char n_str[SHORT_STRING] # "{\null}" +char latex_eol[SHORT_STRING] # "\eol{\\}" +char tex_eol[SHORT_STRING] # "\eol{\cr}" + +begin + if (prt_option[1] == 'l') # LaTeX + call strcpy ("\\newcommand", new_cmd, SHORT_STRING) + else if (prt_option[1] == 't') # TeX + call strcpy ("\\def", new_cmd, SHORT_STRING) + call strcpy ("{\\null}", n_str, SHORT_STRING) + call strcpy ("\\eol{\\\\}", latex_eol, SHORT_STRING) + call strcpy ("\\eol{\\cr}", tex_eol, SHORT_STRING) + + if (showrow) + k = 0 + else + k = 1 + + # Define either \colzero or \cola, depending on showrow. + call printf ("%s") + call pargstr (new_cmd) + call tpr_w_colsep (k) + call printf ("%s\n") + call pargstr (n_str) + + # Define the rest of the column-separators, if any. + k = k + 1 + while (k <= ncp) { + call printf ("%s") + call pargstr (new_cmd) + call tpr_w_colsep (k) + call printf ("{&}\n") + k = k + 1 + } + + # Define \eol. + call printf ("%s") + call pargstr (new_cmd) + if (prt_option[1] == 'l') { # LaTeX + call printf ("%s\n") + call pargstr (latex_eol) + } else if (prt_option[1] == 't') { # TeX + call printf ("%s\n") + call pargstr (tex_eol) + } + + # Define \extline for writing blank lines. + call printf ("%s\\extline{") + call pargstr (new_cmd) + do k = 1, ncp-1 + call printf ("&") + if (showrow) + call printf ("&") + call printf ("\\eol}\n") + + call printf ("\n") +end + + + +# tpr_begin_tbl -- Print begin-table string +# This procedure prints a begin-table string for LaTeX or for TeX. + +procedure tpr_begin_tbl (prt_option, just_flag, ncp, showrow) + +char prt_option[ARB] # i: "latex" or "tex" +int just_flag[ARB] # i: -1, 0, +1 for left, center, right just. +int ncp # i: number of columns to print +bool showrow # i: print row number? +#-- +int k # loop index +char tex_cr[SHORT_STRING] # "\cr" + +begin + if (prt_option[1] == 'l') { # LaTeX + + call printf ("\\begin{tabular}{") + if (showrow) + call printf ("r") # right justify row number + do k = 1, ncp { + if (just_flag[k] == -1) + call printf ("l") # left justify + else if (just_flag[k] == 1) + call printf ("r") # right justify + else + call printf ("c") # center + } + call printf ("}\n") + + } else if (prt_option[1] == 't') { # TeX + + call strcpy ("\\cr", tex_cr, SHORT_STRING) + + if (showrow) { + call printf ("\\halign{\\hfil#") # row number + call printf ("\n&\\quad") + } else { + call printf ("\\halign{") + } + + # First column. + if (just_flag[1] == -1) + call printf ("#\\hfil") # left + else if (just_flag[1] == 1) + call printf ("\\hfil#") # right + else + call printf ("\\hfil#\\hfil") # center + + do k = 2, ncp { + if (just_flag[k] == -1) + call printf ("\n&\\quad#\\hfil") + else if (just_flag[k] == 1) + call printf ("\n&\\quad\\hfil#") + else + call printf ("\n&\\quad\\hfil#\\hfil") + } + call printf ("%s\n\n") # can't use \eol here + call pargstr (tex_cr) + } +end + + +# tpr_end_tbl -- Print end-table string +# This procedure prints an end-table string for LaTeX (or TeX). + +procedure tpr_end_tbl (prt_option) + +char prt_option[ARB] # i: "latex" or "tex" +#-- + +begin + if (prt_option[1] == 'l') # LaTeX + call printf ("\\end{tabular}\n\n") + else if (prt_option[1] == 't') # TeX + call printf ("}\n\n") +end + + + +# tpr_cnames_pr_l -- Print column names +# This procedure prints the column names followed by a blank line. +# (TeX or LaTeX only) + +procedure tpr_cnames_pr_l (colptr, ncp, showrow, showunits, rn_name) + +pointer colptr[ncp] # i: array of column pointers +int ncp # i: number of columns on current page +bool showrow # i: true if row number is to be printed +bool showunits # i: print column units? +char rn_name[ARB] # i: column header for row number +#-- +int cn # loop index for column number +char colname[SZ_COLNAME] # column name +char colunits[SZ_COLUNITS] # column units + +begin + if (showrow) { + call tpr_w_colsep (0) + call printf (rn_name) + } + do cn = 1, ncp { # do for each column on page + call tpr_w_colsep (cn) + call tbcigt (colptr[cn], TBL_COL_NAME, colname, SZ_COLNAME) + call printf ("%s") # trim extra blanks + call pargstr (colname) + } + call printf ("\\eol\n") + + # Also print column units? + if (showunits) { + if (showrow) { + call tpr_w_colsep (0) + } + do cn = 1, ncp { + call tpr_w_colsep (cn) + call tbcigt (colptr[cn], TBL_COL_UNITS, colunits, SZ_COLUNITS) + call printf ("%s") + call pargstr (colunits) + } + call printf ("\\eol\n") + } + call printf ("\\extline\n") +end + + +# prt_row_l -- print a row +# This procedure prints the contents of one row. This LaTeX (or TeX) +# version differs from the plain-print version in the following ways: +# character-string values are printed using %s so that extra blanks +# will not be printed, the column-separators may differ from one column +# to the next, and an end-of-line string is printed. + +procedure prt_row_l (tp, colptr, data_fmt, ncp, rownum, + lenfmt, pagewidth, showrow, orig_row, rn_fmt, rn_width) + +pointer tp # i: pointer to table descriptor +pointer colptr[ncp] # i: array of pointers to column descriptors +char data_fmt[SZ_FMT,ncp] # i: print format for each column +int ncp # i: number of columns on current page +int rownum # i: row number +int lenfmt[ncp] # i: array of lengths of print formats +int pagewidth # i: page width +bool showrow # i: print row number? +bool orig_row # i: show row number from underlying table? +char rn_fmt[ARB] # i: format for printing row number +int rn_width # i: space for printing row number +#-- +pointer sp +pointer cbuf # scratch for character-string buffer +double dbuf # buffer for double-precision elements +real rbuf # buffer for single-precision elements +int ibuf # buffer for integer elements +short sbuf +bool bbuf # buffer for boolean elements +int cn # loop index for column number +int datatype # data type of column +int lentotal # for determining when to print \n +int colsep_width # space needed to print column-separator string +int underlying_row # row number in underlying table +int tbcigi() +errchk tbsirow + +begin + call smark (sp) + call salloc (cbuf, SZ_LINE, TY_CHAR) + + colsep_width = 6 # e.g. "\cola " + + if (showrow) { + call tpr_w_colsep (0) + if (orig_row) { + call tbsirow (tp, rownum, underlying_row) + call printf (rn_fmt) + call pargi (underlying_row) + } else { + call printf (rn_fmt) + call pargi (rownum) # write row number + } + lentotal = colsep_width + rn_width + } else { + lentotal = 0 + } + + do cn = 1, ncp { + + if (lentotal + lenfmt[cn] > pagewidth) { + call printf ("\n") + lentotal = 0 + } + call tpr_w_colsep (cn) # write column-separator string + + datatype = tbcigi (colptr[cn], TBL_COL_DATATYPE) + switch (datatype) { + case (TY_REAL): + call tbegtr (tp, colptr[cn], rownum, rbuf) + call printf (data_fmt[1,cn]) + call pargr (rbuf) + case (TY_DOUBLE): + call tbegtd (tp, colptr[cn], rownum, dbuf) + call printf (data_fmt[1,cn]) + call pargd (dbuf) + case (TY_INT): + call tbegti (tp, colptr[cn], rownum, ibuf) + call printf (data_fmt[1,cn]) + call pargi (ibuf) + case (TY_SHORT): + call tbegts (tp, colptr[cn], rownum, sbuf) + call printf (data_fmt[1,cn]) + call pargs (sbuf) + case (TY_BOOL): + call tbegtb (tp, colptr[cn], rownum, bbuf) + call printf (data_fmt[1,cn]) + call pargb (bbuf) + default: + if (datatype < 0 || datatype == TY_CHAR) { + call tbegtt (tp, colptr[cn], rownum, Memc[cbuf], SZ_LINE) + call printf ("%s") # trim blanks + call pargstr (Memc[cbuf]) + } else { + call error (1, "bad data type; table corrupted?") + } + } + lentotal = lentotal + colsep_width + lenfmt[cn] + } + call printf ("\\eol\n") + + call sfree (sp) +end + + +# tpr_w_colsep -- Write column-separator string +# This procedure writes a string of the form "\cola ", "\colb ", etc +# for n = 1, 2, etc. The case n = 0 gives "\colzero " which is used +# for the row number column. + +procedure tpr_w_colsep (n) + +int n # i: column number or zero +#-- +string alphabet "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +begin + if (n <= 0) { + call printf ("\\colzero ") + } else { + call printf ("\\col%c ") + call pargc (alphabet[n]) + } +end diff --git a/pkg/utilities/nttools/tprint/tprplain.x b/pkg/utilities/nttools/tprint/tprplain.x new file mode 100644 index 00000000..c40217d7 --- /dev/null +++ b/pkg/utilities/nttools/tprint/tprplain.x @@ -0,0 +1,530 @@ +include <ctype.h> # for IS_WHITE +include <tbset.h> +include "tprint.h" + +# tpr_plain_pr -- print contents of table +# This version simply prints the table data. The corresponding procedure +# that prints in TeX/LaTeX format is tpr_latex_pr. +# It may be that all the columns that are to be printed will not fit +# on one page, in which case they are printed in sections: all the rows +# are printed for the first set of columns, then all the rows for the next +# set, etc. +# +# Phil Hodge, 5-Oct-1987 Subroutine created +# Phil Hodge, 7-Oct-1987 prt_row: use different buffer for each data type. +# Phil Hodge, 12-Feb-1988 Include option to align columns with header +# Phil Hodge, 30-Mar-1988 Use a column to control spacing of printout. +# Phil Hodge, 6-Jan-1989 Call tpr_break for new page, also after tpr_cnames_pr +# Phil Hodge, 2-Apr-1993 In prt_row, include short datatype. +# Phil Hodge, 5-Jul-1993 Include option to print column units. +# Phil Hodge, 16-Feb-1995 Print "#" before header lines to comment them out. +# Phil Hodge, 26-Mar-1998 Add orig_row to calling sequence, use in prt_row; +# remove showrow from calling sequences of +# tpr_break and tpr_cnames_pr. +# Phil Hodge, 18-Jan-1999 Get boolean as string, to preserve indef values. +# Phil Hodge, 30-Mar-1999 Delete declaration of bbuf from prt_row. +# Phil Hodge, 9-Aug-1999 Print all array elements; +# move code for printing blank lines into prt_row; +# change the calling sequence of tpr_space; +# delete data_fmt and subroutine tpr_g_fmt. +# Phil Hodge, 3-Jul-2000 In tpr_pfmt, use "%-s" format for the last column +# on a page, if the column should be left justified. +# Phil Hodge, 2-Nov-2000 Remove the restriction that no more than MAXCOLS +# columns can be printed on one page. + +procedure tpr_plain_pr (tp, cptr, nprint, s_cp, lgroup, + range_string, pagewidth, pagelength, + showrow, orig_row, showhdr, showunits, align) + +pointer tp # i: pointer to table descriptor +pointer cptr[nprint] # i: array of pointers to column descriptors +int nprint # i: number of columns to print +pointer s_cp # i: pointer to column to control spacing +int lgroup # i: print blank line after this many lines +char range_string[ARB] # i: string which gives ranges of row numbers +int pagewidth # i: page width +int pagelength # i: number of data lines per page +bool showrow # i: true if row number is to be printed +bool orig_row # i: show row number from underlying table? +bool showhdr # i: print column names? +bool showunits # i: print column units? +bool align # i: override print fmt to align col & name? +#-- +pointer sp +pointer colptr # ptr to descriptors for columns on current page +pointer lenfmt # ptr to lengths of print fmt for cols on page +pointer cn_fmt # formats for printing column values +char rn_fmt[SZ_FMT] # format for printing row numbers +char rn_name[SZ_ROW_HDR] # row number header: "# row" +char rn_units[SZ_ROW_HDR] # "# " printed in the line for units +char percent # '%' +int nrows # total number of rows in table +int rn_width # width needed for printing row number +int lcp # column number of leftmost column on page +int ncp # number of columns on current page +int rownum # row number +int linenum # number of lines of data printed +int ranges[3,MAX_RANGES] # ranges of row numbers +int nvalues # returned by decode_ranges and ignored +int stat # returned by get_next_number +bool done # flag for terminating while loop on rows +int decode_ranges(), get_next_number(), tbpsta() + +begin + # Allocate space for format strings for printing column names and + # values. Allocate arrays for pointers to column descriptors and + # the ascii width of each column. Allow enough space to print all + # columns on one page. + call smark (sp) + call salloc (cn_fmt, (SZ_FMT+1)*nprint, TY_CHAR) + call salloc (colptr, nprint, TY_POINTER) + call salloc (lenfmt, nprint, TY_POINTER) + + nrows = tbpsta (tp, TBL_NROWS) + + if (decode_ranges (range_string, ranges, MAX_RANGES, nvalues) != OK) + call error (1, "bad range of row numbers") + + # rn_name, rn_units, rn_fmt and rn_width must be consistent. + if (showrow) { + # These two strings are printed above the row number + # in the line for column names and in the line for column units. + call strcpy ("# row", rn_name, SZ_ROW_HDR) + call strcpy ("# ", rn_units, SZ_ROW_HDR) + rn_width = SZ_ROW_HDR # space for printing row number + } else if (showhdr) { + call strcpy ("#", rn_name, SZ_ROW_HDR) + call strcpy ("#", rn_units, SZ_ROW_HDR) + rn_width = 1 # space for "#" + } else { + rn_name[1] = EOS # no header printed + rn_units[1] = EOS + rn_width = 0 + } + percent = '%' + call sprintf (rn_fmt, SZ_FMT, "%c%dd") # --> %5d + call pargc (percent) + call pargi (SZ_ROW_HDR) + + lcp = 1 # initialize + while (lcp <= nprint) { # do for each page + + # Get column pointers for current page + call get_page (tp, cptr, lcp, nprint, pagewidth-rn_width, + align, showunits, Memi[colptr], Memi[lenfmt], ncp) + + # Fill array of print formats. + call tpr_pfmt (Memi[colptr], Memi[lenfmt], align, Memc[cn_fmt], ncp) + + # Print a form feed if this is not the first page and the user + # has requested page breaks. + if (lcp > 1) { + if (pagelength > 0) + call printf ("\f\n") + else + call printf ("\n") + } + # Print column names. + if (showhdr) + call tpr_cnames_pr (Memi[colptr], Memc[cn_fmt], ncp, + showunits, rn_name, rn_units) + + # Print each row that is to be printed. + linenum = 0 # initialize line counter + rownum = 0 # initialize get_next_number + stat = get_next_number (ranges, rownum) # get first row number + done = (stat == EOF) || (rownum > nrows) + + while ( !done ) { + + # Print values in current row. + call prt_row (tp, Memi[colptr], Memc[cn_fmt], ncp, + linenum, pagelength, s_cp, lgroup, + rn_fmt, rn_name, rn_units, + rownum, showrow, orig_row, showhdr, showunits) + + # Get next row number. + stat = get_next_number (ranges, rownum) + done = (stat == EOF) || (rownum > nrows) + } + + lcp = lcp + ncp # next set of columns to be printed + } + call sfree (sp) +end + +# tpr_break -- print a page break +# This routine prints a form feed ('\f') if appropriate. If pagelength +# is zero we're not printing page breaks anyway, and if linenum is zero +# we've already printed the header, so nothing is done. Otherwise, +# if linenum is zero mod pagelength print a page break, and if showhdr +# print the header. + +procedure tpr_break (linenum, pagelength, showhdr, showunits, + colptr, cn_fmt, ncp, rn_name, rn_units) + +int linenum # io: number of lines of data printed +int pagelength # i: number of data lines per page +bool showhdr # i: print column names? +bool showunits # i: also print column units? +pointer colptr[ARB] # i: array of column pointers +char cn_fmt[SZ_FMT,ARB] # i: array of print formats +int ncp # i: number of columns on current page +char rn_name[ARB] # i: column header for row number +char rn_units[ARB] # i: printed below rn_name +#-- + +begin + if (pagelength > 0) { + if (linenum > 0) { + if (mod (linenum, pagelength) == 0) { + call printf ("\f\n") + if (showhdr) # print column names + call tpr_cnames_pr (colptr, cn_fmt, ncp, + showunits, rn_name, rn_units) + } + } + } +end + + +# get_page -- get columns for page +# This procedure determines which columns will fit on the current page. +# Each column is assumed to begin with a column separator which is a +# single space. + +procedure get_page (tp, cptr, lcp, nprint, pagewidth, align, + showunits, colptr, lenfmt, ncp) + +pointer tp # i: pointer to table descriptor +pointer cptr[nprint] # i: array of pointers to all column descr +int lcp # i: column number of leftmost column on page +int nprint # i: number of columns to print +int pagewidth # i: page width available for writing +bool align # i: override print fmt to align col & name? +bool showunits # i: also print column units? +pointer colptr[ARB] # o: pointers for columns on current page +int lenfmt[ARB] # o: length of print format for each col +int ncp # o: number of columns on current page +#-- +char colname[SZ_COLNAME] # column name for error message +int lentotal # sum of lenfmt plus a space for each column +int nextc # column counter +int tpr_lenfmt() + +begin + # Assume we can print at least one column, truncated if necessary. + ncp = 1 + colptr[1] = cptr[lcp] + # Get width for printing column. + lenfmt[1] = tpr_lenfmt (colptr[1], align, showunits) + if (lenfmt[1] > pagewidth-1) { + call tbcigt (colptr[1], TBL_COL_NAME, colname, SZ_COLNAME) + call eprintf ("caution: column %s will be truncated\n") + call pargstr (colname) + lenfmt[1] = pagewidth-1 + } + + lentotal = lenfmt[1] + 1 # add one for leading space + + # The loop continuation conditions are: + # the columns fit on the page, + # there are still columns that have not been included. + while (lentotal < pagewidth && lcp+ncp-1 < nprint) { + nextc = ncp + 1 + colptr[nextc] = cptr[lcp+nextc-1] + # get lenfmt + lenfmt[nextc] = tpr_lenfmt (colptr[nextc], align, showunits) + lentotal = lentotal + lenfmt[nextc] + 1 # one for leading space + if (lentotal <= pagewidth) + ncp = nextc # = ncp + 1 + } +end + + + +# tpr_lenfmt -- get length of print format +# This function returns the length of the print format for a column. +# If align is true then the column name will be gotten, and the length +# of the print format that is returned will be at least as large as +# the length of the column name. The length will also be at least five, +# since that is the length of the word INDEF. + +int procedure tpr_lenfmt (cptr, align, showunits) + +pointer cptr # i: pointer to column descriptor +bool align # i: true ==> may increase length of print fmt +bool showunits # i: also print column units? +#-- +char colname[SZ_COLNAME] # name of column +char colunits[SZ_COLUNITS] # column units +int lenfmt # length of print format +int len_name # length of column name +int len_units # length of column units +int tbcigi(), strlen() + +begin + lenfmt = tbcigi (cptr, TBL_COL_FMTLEN) + + if ( align ) { + + call tbcigt (cptr, TBL_COL_NAME, colname, SZ_COLNAME) + len_name = strlen (colname) + + # Length >= length of column name or the word "INDEF". + lenfmt = max (lenfmt, len_name, 5) + + if (showunits) { + call tbcigt (cptr, TBL_COL_UNITS, colunits, SZ_COLUNITS) + len_units = strlen (colunits) + lenfmt = max (lenfmt, len_units) + } + } + return (lenfmt) +end + + + +# tpr_pfmt -- Get print formats +# This procedure fills an array with print formats of the form %ws. +# These can be used for printing the column names, units and data values. + +procedure tpr_pfmt (colptr, lenfmt, align, cn_fmt, ncp) + +pointer colptr[ncp] # i: array of column pointers +int lenfmt[ncp] # i: array of lengths of print formats +bool align # i: override print fmt to align col & name? +char cn_fmt[SZ_FMT,ncp] # o: array of print formats +int ncp # i: number of columns on current page +#-- +char fmt[SZ_COLFMT] # unmodified print format as gotten from table +int cn # loop index for column number + +begin + do cn = 1, ncp { # do for each column on page + + # Get print format for current column. + call tbcigt (colptr[cn], TBL_COL_FMT, fmt, SZ_COLFMT) + + cn_fmt[1,cn] = '%' + if (fmt[2] == '-') { # left justification + if (cn == ncp) { + call sprintf (cn_fmt[2,cn], SZ_FMT-1, "-s") + } else { + call sprintf (cn_fmt[2,cn], SZ_FMT-1, "-%ds") + call pargi (lenfmt[cn]) + } + } else { # right justification + call sprintf (cn_fmt[2,cn], SZ_FMT-1, "%ds") + call pargi (lenfmt[cn]) + } + } +end + + +# tpr_cnames_pr -- Print column names +# This procedure prints the column names and units and an extra blank line. +# A comment character ("#") is printed at the beginning of the line; this +# is new as of 1995 Feb 16. + +procedure tpr_cnames_pr (colptr, cn_fmt, ncp, + showunits, rn_name, rn_units) + +pointer colptr[ncp] # i: array of column pointers +char cn_fmt[SZ_FMT,ncp] # i: array of print formats +int ncp # i: number of columns on current page +bool showunits # i: also print column units? +char rn_name[ARB] # i: column header for row number +char rn_units[ARB] # i: printed below rn_name +#-- +char colname[SZ_COLNAME] # column name +char colunits[SZ_COLUNITS] # column units +int cn # loop index for column number + +begin + call printf (rn_name) # "# row" or "#" + + do cn = 1, ncp { # do for each column on page + call printf (" ") + call tbcigt (colptr[cn], TBL_COL_NAME, colname, SZ_COLNAME) + call printf (cn_fmt[1,cn]) + call pargstr (colname) + } + call printf ("\n") + + # Also print column units? + if (showunits) { + call printf (rn_units) # "# " or "#" + do cn = 1, ncp { + call printf (" ") + call tbcigt (colptr[cn], TBL_COL_UNITS, colunits, SZ_COLUNITS) + call printf (cn_fmt[1,cn]) + call pargstr (colunits) + } + call printf ("\n") + } + + call printf ("\n") +end + + +# prt_row -- print a row +# This procedure prints the contents of one row. + +procedure prt_row (tp, colptr, cn_fmt, ncp, + linenum, pagelength, s_cp, lgroup, + rn_fmt, rn_name, rn_units, + rownum, showrow, orig_row, showhdr, showunits) + +pointer tp # i: pointer to table descriptor +pointer colptr[ncp] # i: array of pointers to column descriptors +char cn_fmt[SZ_FMT,ncp] # i: array of print formats +int ncp # i: number of columns on current page +int linenum # io: number of lines of data printed +int pagelength # i: number of data lines per page +pointer s_cp # i: pointer to column to control spacing +int lgroup # i: print blank line after this many lines +char rn_fmt[ARB] # i: format for printing row number +char rn_name[ARB] # i: row number header: "# row" +char rn_units[ARB] # i: "# " printed in the line for units +int rownum # i: row number +bool showrow # i: print row number? +bool orig_row # i: show row number from underlying table? +bool showhdr # i: was a header printed? +bool showunits # i: print column units? +#-- +pointer sp +pointer cbuf # scratch for character-string buffer +pointer nelem # array length for each column +int max_nelem # maximum of array lengths +bool has_arrays # true if any column contains arrays +bool has_scalars # true if not all columns contain arrays +int cn # loop index for column number +int element # loop index for array element number +int underlying_row # row number in underlying table +int ip # first non-blank character in cbuf +int s_flag # YES if we should print a line for spacing +int tbcigi(), tbagtt() +errchk tbsirow + +begin + call smark (sp) + call salloc (cbuf, SZ_LINE, TY_CHAR) + call salloc (nelem, ncp, TY_INT) + + # Get the array length for each column. + max_nelem = 1 # initial values + if (showrow) + has_scalars = true # row number is a scalar + else + has_scalars = false + + do cn = 1, ncp { + Memi[nelem+cn-1] = tbcigi (colptr[cn], TBL_COL_LENDATA) + if (Memi[nelem+cn-1] > max_nelem) + max_nelem = Memi[nelem+cn-1] + if (Memi[nelem+cn-1] == 1) + has_scalars = true + } + has_arrays = (max_nelem > 1) + + # If all columns contain arrays, print a blank line as a separator. + if (!has_scalars && rownum > 1) + call printf ("\n") + + # Loop over the number of elements in the longest array. + do element = 1, max_nelem { + + # Print a page break if appropriate. + call tpr_break (linenum, pagelength, showhdr, showunits, + colptr, cn_fmt, ncp, rn_name, rn_units) + + # Print a blank line if the value in the column has changed + # or if a group of lgroup lines has been printed. + call tpr_space (tp, s_cp, lgroup, + rownum, element, max_nelem, pagelength, linenum, s_flag) + if (s_flag == YES) { + call printf ("\n") + linenum = linenum + 1 + # Check whether we should also print a page break. + call tpr_break (linenum, pagelength, showhdr, showunits, + colptr, cn_fmt, ncp, rn_name, rn_units) + } + + if (showrow) { + if (element == 1) { + if (orig_row) { + call tbsirow (tp, rownum, underlying_row) + call printf (rn_fmt) + call pargi (underlying_row) + } else { + call printf (rn_fmt) + call pargi (rownum) + } + } else { + call printf (" ") # SZ_ROW_HDR blanks + } + } else if (showhdr) { + # Corresponds to the "#" at the beginning of header lines. + call printf (" ") + } + + do cn = 1, ncp { + + # Even if no row number is printed, start with a space. + call printf (" ") # space between columns + + # Does the current column contain arrays? + if (Memi[nelem+cn-1] > 1) { + + if (element <= Memi[nelem+cn-1]) { + if (tbagtt (tp, colptr[cn], rownum, + Memc[cbuf], SZ_LINE, element, 1) < 1) + call error (1, "can't read array element") + call tpr_noblank (Memc[cbuf], ip) + } else { + Memc[cbuf] = EOS + ip = 1 + } + call printf (cn_fmt[1,cn]) + call pargstr (Memc[cbuf+ip-1]) + + } else if (element == 1) { + + # This is a scalar column. + call tbegtt (tp, colptr[cn], rownum, Memc[cbuf], SZ_LINE) + call tpr_noblank (Memc[cbuf], ip) + call printf (cn_fmt[1,cn]) + call pargstr (Memc[cbuf+ip-1]) + + } else { + + # Print a blank field for a scalar column to match array + # element > 1 for array column(s). + call printf (cn_fmt[1,cn]) + call pargstr ("") + } + } + call printf ("\n") + linenum = linenum + 1 + } + call sfree (sp) +end + +procedure tpr_noblank (buf, ip) + +char buf[ARB] # io: input string (trailing blanks will be truncted) +int ip # o: first non-blank character in buf +#-- +int strlen() + +begin + ip = strlen (buf) + while (ip >= 1 && IS_WHITE(buf[ip])) { # trim trailing blanks + buf[ip] = EOS + ip = ip - 1 + } + ip = 1 + while (IS_WHITE(buf[ip])) # trim leading blanks + ip = ip + 1 +end |