diff options
author | Joe Hunkeler <jhunkeler@gmail.com> | 2015-08-11 16:51:37 -0400 |
---|---|---|
committer | Joe Hunkeler <jhunkeler@gmail.com> | 2015-08-11 16:51:37 -0400 |
commit | 40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch) | |
tree | 4464880c571602d54f6ae114729bf62a89518057 /pkg/utilities/nttools/ttranspose | |
download | iraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz |
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'pkg/utilities/nttools/ttranspose')
-rw-r--r-- | pkg/utilities/nttools/ttranspose/mkpkg | 11 | ||||
-rw-r--r-- | pkg/utilities/nttools/ttranspose/ttranspose.x | 419 | ||||
-rw-r--r-- | pkg/utilities/nttools/ttranspose/ttrflip.x | 266 |
3 files changed, 696 insertions, 0 deletions
diff --git a/pkg/utilities/nttools/ttranspose/mkpkg b/pkg/utilities/nttools/ttranspose/mkpkg new file mode 100644 index 00000000..6118a47e --- /dev/null +++ b/pkg/utilities/nttools/ttranspose/mkpkg @@ -0,0 +1,11 @@ +# Update the ttranspose application code in the ttools package library + +$checkout libpkg.a ../ +$update libpkg.a +$checkin libpkg.a ../ +$exit + +libpkg.a: + ttranspose.x <error.h> <tbset.h> + ttrflip.x + ; diff --git a/pkg/utilities/nttools/ttranspose/ttranspose.x b/pkg/utilities/nttools/ttranspose/ttranspose.x new file mode 100644 index 00000000..1bf99d9e --- /dev/null +++ b/pkg/utilities/nttools/ttranspose/ttranspose.x @@ -0,0 +1,419 @@ +include <error.h> # for EA_WARN +include <fset.h> # to check whether input or output is redirected +include <tbset.h> + +# ttranspose -- transpose or flip a table +# This task can be used to transpose a table so that input rows become +# output columns and input columns become output rows. Another option +# is to flip the table horizontally, that is, the first input column is +# the last output column. Finally, the table can be flipped vertically, +# i.e., the first input row is the last output row. Any combination of +# these operations may be performed. +# +# Phil Hodge, 30-Nov-1994 Task created. +# Phil Hodge, 4-Oct-1995 Modify to use tbn instead of fnt. +# Phil Hodge, 12-Jun-1998 Initialize maxwidth using tbcftl in ttr_compare. +# Phil Hodge, 8-Apr-1999 Call tbfpri. +# Phil Hodge, 8-Jun-1999 Set input/output to STDIN/STDOUT if redirected. + +procedure ttranspose() + +pointer innames # scratch for names of input tables +pointer outnames # scratch for names of output tables +pointer action # scratch for operations to perform +bool verbose # print table names? +#-- +pointer sp +pointer ilist, olist # tbn pointers for input & output lists +pointer intable # scratch for name of an input table +pointer outtable # scratch for name of an output table +pointer itp, otp # pointers to input & output table structs +pointer icp, ocp # pointers to arrays of column descriptors +int op[2] # mapping of (columns,rows) from input to output +int dtype # data type of columns +int nelem # number of elements in array +int irows, orows # number of rows in input, output tables +int icols, ocols # number of columns in input, output tables +int i # loop index +int junk +int num_out # number of output table names +int phu_copied # set by tbfpri and ignored +bool transpose # true if table will be transposed, not just flipped +bool to_stdout # true if output is to STDOUT +bool clgetb(), streq() +int fstati() +pointer tbnopen() +int tbnlen(), tbnget() +pointer tbtopn(), tbcnum() +int tbpsta() +errchk ttr_compare, tbfpri, ttr_create, ttr_trans, ttr_flip +string SKIP "Table %s will be skipped:\n" + +begin + call smark (sp) + call salloc (innames, SZ_LINE, TY_CHAR) + call salloc (outnames, SZ_LINE, TY_CHAR) + call salloc (intable, SZ_LINE, TY_CHAR) + call salloc (outtable, SZ_LINE, TY_CHAR) + call salloc (action, SZ_LINE, TY_CHAR) + + if (fstati (STDIN, F_REDIR) == YES) + call strcpy ("STDIN", Memc[innames], SZ_LINE) + else + call clgstr ("intable", Memc[innames], SZ_LINE) + + if (fstati (STDOUT, F_REDIR) == YES) + call strcpy ("STDOUT", Memc[outnames], SZ_LINE) + else + call clgstr ("outtable", Memc[outnames], SZ_LINE) + + call clgstr ("action", Memc[action], SZ_LINE) + verbose = clgetb ("verbose") + + # Interpret the list of operations. + call ttr_opcode (Memc[action], op, transpose) + + ilist = tbnopen (Memc[innames]) + olist = tbnopen (Memc[outnames]) + + to_stdout = false # may be updated below + num_out = tbnlen (olist) + # Get the first output name now, and then rewind the list. + junk = tbnget (olist, Memc[outtable], SZ_LINE) + call tbnrew (olist) + + if (tbnlen (ilist) != num_out) { + if (num_out == 1 && streq (Memc[outtable], "STDOUT")) { + # It's OK to have multiple input tables and just one output + # if the latter is STDOUT. + to_stdout = true + } else { + call tbnclose (olist) + call tbnclose (ilist) + call error (1, "Input and output lists not the same length.") + } + } + + # Do for each table in the list. + while (tbnget (ilist, Memc[intable], SZ_LINE) != EOF) { + if (num_out > 1) + junk = tbnget (olist, Memc[outtable], SZ_LINE) + + # Open input table and get number of rows and columns. + itp = tbtopn (Memc[intable], READ_ONLY, NULL) + irows = tbpsta (itp, TBL_NROWS) + icols = tbpsta (itp, TBL_NCOLS) + call tbtnam (itp, Memc[intable], SZ_LINE) # get full table name + + # Allocate space for pointers to column descriptors. + call malloc (icp, icols, TY_POINTER) + + # Get column pointers for input table. + do i = 1, icols + Memi[icp+i-1] = tbcnum (itp, i) + + iferr { + # Check that data types of columns are all the same. + call ttr_compare (itp, Memi[icp], icols, + transpose, dtype, nelem) + + # Create output table. + call tbfpri (Memc[intable], Memc[outtable], phu_copied) + call ttr_create (itp, otp, Memi[icp], ocp, Memc[outtable], + op, transpose, irows, icols, orows, ocols, dtype, nelem) + } then { + call mfree (icp, TY_POINTER) + call tbtclo (itp) + call eprintf (SKIP) + call pargstr (Memc[intable]) + call erract (EA_WARN) + next + } + + if (verbose) { + call printf ("%s --> %s\n") + call pargstr (Memc[intable]) + call pargstr (Memc[outtable]) + call flush (STDOUT) + } + + # Copy table data. + iferr { + if (transpose) { + call ttr_trans (itp, otp, Memi[icp], Memi[ocp], + irows, icols, orows, ocols, op, dtype, nelem) + } else { + call ttr_flip (itp, otp, Memi[icp], Memi[ocp], + irows, icols, op) + } + } then { + call mfree (ocp, TY_POINTER) + call mfree (icp, TY_POINTER) + call tbtclo (otp) + call tbtclo (itp) + call tbtdel (Memc[outtable]) + call eprintf (SKIP) + call pargstr (Memc[intable]) + call erract (EA_WARN) + next + } + + call mfree (ocp, TY_POINTER) + call mfree (icp, TY_POINTER) + iferr { + call tbtclo (otp) + } then { + call eprintf (SKIP) + call pargstr (Memc[intable]) + call erract (EA_WARN) + } + call tbtclo (itp) + } + + call tbnclose (olist) + call tbnclose (ilist) + call sfree (sp) +end + +procedure ttr_opcode (action, op, transpose) + +char action[ARB] # i: list of operations to perform +int op[2] # o: combined operations +bool transpose # o: true if table will be transposed, not just flipped +#-- +int i +int prev[2] # previous op +int slen # length of string +int strlen() + +begin + slen = strlen (action) + + prev[1] = 1 # initial values + prev[2] = 2 + + do i = 1, slen { + if (action[i] == 't' || action[i] == '/') { + # transpose + op[1] = prev[2] + op[2] = prev[1] + } else if (action[i] == 'h' || action[i] == '-') { + # flip horizontally, i.e. first column <--> last col + op[1] = -prev[1] + op[2] = prev[2] + } else if (action[i] == 'v' || action[i] == '|') { + # flip vertically, i.e. first row <--> last row + op[1] = prev[1] + op[2] = -prev[2] + } else if (action[i] == ',' || action[i] == ' ') { + ; + } else { + call error (1, "'action' must use only t, h, v") + } + prev[1] = op[1] # save for next loop + prev[2] = op[2] + } + + # After all the operations, will we actually transpose the table, + # or just flip it? + transpose = (abs (op[1]) == 2) +end + +# ttr_compare -- compare data types and array lengths + +procedure ttr_compare (itp, icp, icols, transpose, dtype, nelem) + +pointer itp # i: pointer to input table struct +pointer icp[icols] # i: array of pointers to input column descriptors +int icols # i: number of columns in input table +bool transpose # i: true if table will be transposed, not just flipped +int dtype # o: data type of columns +int nelem # o: length of array stored at each row,column +#-- +int dtype2, nelem2 # data type and array length of column to compare +int width # width of a particular column +int maxwidth # max width of column in text table +int i +int tbpsta(), tbcigi() + +begin + # Get info about first column so we can compare with other columns. + dtype = tbcigi (icp[1], TBL_COL_DATATYPE) + nelem = tbcigi (icp[1], TBL_COL_LENDATA) + if (dtype == TY_CHAR) { # old style, change it + dtype = -nelem + nelem = 1 + } + + # We don't need to check column data types if we're not actually + # transposing the table. + if (!transpose) + return + + if (tbpsta (itp, TBL_WHTYPE) == TBL_TYPE_TEXT) { + + # For a text table, we can permit different input data types + # if we set the output type to text. + + call tbcftl (icp[1], maxwidth) # maxwidth updated in loop + do i = 2, icols { + + call tbcftl (icp[i], width) # get width of current column + maxwidth = max (maxwidth, width) + + dtype2 = tbcigi (icp[i], TBL_COL_DATATYPE) + if (dtype > 0 && dtype != dtype2) { + # They're not the same; change to char data type. + dtype = -maxwidth + } + } + if (dtype < 0) + dtype = -maxwidth + + } else { # not a text table + + # Compare first column with subsequent columns. + do i = 2, icols { + + dtype2 = tbcigi (icp[i], TBL_COL_DATATYPE) + nelem2 = tbcigi (icp[i], TBL_COL_LENDATA) + if (dtype2 == TY_CHAR) { + dtype2 = -nelem2 + nelem2 = 1 + } + + if (dtype < 0) { + # For character columns, allow different lengths for + # input, but change to maximum length for output. + dtype = min (dtype, dtype2) # max absolute value + + } else if (dtype != dtype2) { + + # Promote real to double, short to int, and bool to + # any other type. + if (dtype == TY_REAL && dtype2 == TY_DOUBLE || + dtype == TY_DOUBLE && dtype2 == TY_REAL) { + dtype = TY_DOUBLE + } else if (dtype == TY_INT && dtype2 == TY_SHORT || + dtype == TY_SHORT && dtype2 == TY_INT) { + dtype = TY_INT + } else if (dtype == TY_BOOL) { + dtype = dtype2 # promote to other type + } else if (dtype2 == TY_BOOL) { + ; # OK to convert to any type + } else { + call error (1, "columns are not all the same data type") + } + } + + if (nelem != nelem2) + call error (1, "column array lengths are not all the same") + } + } +end + +# ttr_create -- create output table +# This routine creates the output table, defines output columns, +# and copies header parameters. +# +# Note the following, which can be a bit confusing. In the case that +# the table is to be flipped horizontally but not transposed, columns are +# defined in the output table in the reverse order from the corresponding +# columns in the input table, but the column pointers themselves are stored +# in their arrays in the same order. That is, icp[i] refers to the same +# column as Memi[ocp+i-1], except of course that icp[i] is in the input +# table and Memi[ocp+i-1] is in the output table. "Same column" means +# that the column descriptions and contents are the same, but the column +# number will in general be different; icp[1] is the first column in the +# input table, Memi[ocp] is the last column in the output table, and they +# will have the same name, etc. + +procedure ttr_create (itp, otp, icp, ocp, outtable, + op, transpose, irows, icols, orows, ocols, dtype, nelem) + +pointer itp # i: pointer to input table struct +pointer otp # o: pointer to output table struct +pointer icp[icols] # i: array of pointers to input column descriptors +pointer ocp # o: pointer to array of pointers to output col descr +char outtable[ARB] # io: name of output table (extension may be appended) +int op[2] # i: operation code +bool transpose # i: true if table will be transposed, not just flipped +int irows # i: number of rows in input table +int icols # i: number of columns in input table +int orows # o: number of rows in output table +int ocols # o: number of columns in output table +int dtype # i: data type of columns +int nelem # i: length of array stored at each row,column +#-- +char colname[SZ_COLNAME] # name of current column +char colunits[SZ_COLUNITS] # units for current column +char colfmt[SZ_COLFMT] # print format for current column +int datatype # data type of current column +int lenarray # number of elements for current column +int lenfmt # space required to print column +int colnum # column number +int i # loop index +int i_start, i_end, i_incr # loop limits for index i +int maxpar # space allocated for header parameters +pointer tbtopn() +int tbpsta() + +begin + # Allocate space for array of column pointers for output table. + if (transpose) { + orows = icols + ocols = irows + } else { # don't transpose + orows = irows + ocols = icols + } + call malloc (ocp, ocols, TY_POINTER) + + # Create output table. + otp = tbtopn (outtable, NEW_FILE, NULL) + if (tbpsta (itp, TBL_WHTYPE) == TBL_TYPE_TEXT) + call tbpset (otp, TBL_WHTYPE, TBL_TYPE_TEXT) + + # Set enough space for all header parameters from input. + maxpar = tbpsta (itp, TBL_MAXPAR) + call tbpset (otp, TBL_MAXPAR, maxpar) + + # Create output columns. + if (transpose) { + + # Assign dummy column names, with null units and default format. + do i = 1, ocols { + call sprintf (colname, SZ_COLNAME, "c%d") + call pargi (i) + call tbcdef (otp, Memi[ocp+i-1], + colname, "", "", dtype, nelem, 1) + } + + } else { + + # We're not transposing, so retain column names, etc. + if (op[1] > 0) { + # retain order of columns + i_start = 1 + i_end = icols + i_incr = 1 + } else { + # flip by defining last column first + i_start = icols + i_end = 1 + i_incr = -1 + } + + do i = i_start, i_end, i_incr { + call tbcinf (icp[i], colnum, colname, colunits, colfmt, + datatype, lenarray, lenfmt) + call tbcdef (otp, Memi[ocp+i-1], + colname, colunits, colfmt, datatype, lenarray, 1) + } + } + call tbtcre (otp) + call tbtnam (otp, outtable, SZ_LINE) # get full table name + + # Copy all header parameters from input to output. + call tbhcal (itp, otp) +end diff --git a/pkg/utilities/nttools/ttranspose/ttrflip.x b/pkg/utilities/nttools/ttranspose/ttrflip.x new file mode 100644 index 00000000..3c008f68 --- /dev/null +++ b/pkg/utilities/nttools/ttranspose/ttrflip.x @@ -0,0 +1,266 @@ +# This file contains ttr_trans and ttr_flip. The former copies data +# from one table to another and transposes rows and columns, while the +# latter copies data without transposing. Either routine may also flip +# rows and/or columns, i.e. first input row to last output row, or first +# input column to last input column. +# +# Phil Hodge, 30-Nov-1994 Subroutines created. + +# ttr_trans -- copy data from input to output +# This routine transposes a table. + +procedure ttr_trans (itp, otp, icp, ocp, + irows, icols, orows, ocols, op, dtype, nelem) + +pointer itp # i: pointer to input table struct +pointer otp # i: pointer to output table struct +pointer icp[icols] # i: array of pointers to input column descriptors +pointer ocp[irows] # i: array of pointers to output column descriptors +int irows # i: number of rows in input table +int icols # i: number of columns in input table +int orows # i: number of rows in output table +int ocols # i: number of columns in output table +int op[2] # i: mapping of (columns,rows) from input to output +int dtype # i: data type of column +int nelem # i: length of array stored at each row,column +#-- +pointer sp +pointer buf # scratch for copying array entries +int clen # length of char string (= -dtype) +int i, j # loop indices for input table +int oi, oj # loop indices for output table +int oj_start # starting value for oj +int oi_incr, oj_incr # increments in oi, oj + +# buffers for copying one element: +pointer cbuf +double dbuf +real rbuf +int ibuf +short sbuf +bool bbuf + +int nret # number of array elements actually read and written +int tbagtd(), tbagtr(), tbagti(), tbagts(), tbagtb(), tbagtt() +errchk tbegtd, tbegtr, tbegti, tbegts, tbegtb, tbegtt, + tbeptd, tbeptr, tbepti, tbepts, tbeptb, tbeptt, + tbagtd, tbagtr, tbagti, tbagts, tbagtb, tbagtt, + tbaptd, tbaptr, tbapti, tbapts, tbaptb, tbaptt + +begin + call smark (sp) + + # Assign values for the beginning and increment for the loops + # on oi and oj. + if (op[1] > 0) { + oi = 1 + oi_incr = 1 + } else { + oi = ocols # = irows + oi_incr = -1 + } + if (op[2] > 0) { + oj_start = 1 + oj_incr = 1 + } else { + oj_start = orows # = icols + oj_incr = -1 + } + + if (dtype < 0) + clen = -dtype + + if (nelem == 1) { + + if (dtype == TY_REAL) { + do j = 1, irows { + oj = oj_start # oj, not oi, because we're transposing + do i = 1, icols { + call tbegtr (itp, icp[i], j, rbuf) + call tbeptr (otp, ocp[oi], oj, rbuf) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else if (dtype == TY_DOUBLE) { + do j = 1, irows { + oj = oj_start + do i = 1, icols { + call tbegtd (itp, icp[i], j, dbuf) + call tbeptd (otp, ocp[oi], oj, dbuf) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else if (dtype == TY_INT) { + do j = 1, irows { + oj = oj_start + do i = 1, icols { + call tbegti (itp, icp[i], j, ibuf) + call tbepti (otp, ocp[oi], oj, ibuf) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else if (dtype == TY_SHORT) { + do j = 1, irows { + oj = oj_start + do i = 1, icols { + call tbegts (itp, icp[i], j, sbuf) + call tbepts (otp, ocp[oi], oj, sbuf) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else if (dtype == TY_BOOL) { + do j = 1, irows { + oj = oj_start + do i = 1, icols { + call tbegtb (itp, icp[i], j, bbuf) + call tbeptb (otp, ocp[oi], oj, bbuf) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else if (dtype < 0) { + call salloc (cbuf, SZ_LINE, TY_CHAR) + do j = 1, irows { + oj = oj_start + do i = 1, icols { + call tbegtt (itp, icp[i], j, Memc[cbuf], SZ_LINE) + call tbeptt (otp, ocp[oi], oj, Memc[cbuf]) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else { + call error (1, "invalid data type") + } + + } else { # each entry is an array + + if (dtype > 0) + call salloc (buf, nelem, dtype) + + if (dtype == TY_REAL) { + do j = 1, irows { + oj = oj_start + do i = 1, icols { + nret = tbagtr (itp, icp[i], j, Memr[buf], 1, nelem) + call tbaptr (otp, ocp[oi], oj, Memr[buf], 1, nret) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else if (dtype == TY_DOUBLE) { + do j = 1, irows { + oj = oj_start + do i = 1, icols { + nret = tbagtd (itp, icp[i], j, Memd[buf], 1, nelem) + call tbaptd (otp, ocp[oi], oj, Memd[buf], 1, nret) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else if (dtype == TY_INT) { + do j = 1, irows { + oj = oj_start + do i = 1, icols { + nret = tbagti (itp, icp[i], j, Memi[buf], 1, nelem) + call tbapti (otp, ocp[oi], oj, Memi[buf], 1, nret) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else if (dtype == TY_SHORT) { + do j = 1, irows { + oj = oj_start + do i = 1, icols { + nret = tbagts (itp, icp[i], j, Mems[buf], 1, nelem) + call tbapts (otp, ocp[oi], oj, Mems[buf], 1, nret) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else if (dtype == TY_BOOL) { + do j = 1, irows { + oj = oj_start + do i = 1, icols { + nret = tbagtb (itp, icp[i], j, Memb[buf], 1, nelem) + call tbaptb (otp, ocp[oi], oj, Memb[buf], 1, nret) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else if (dtype < 0) { + call salloc (buf, (clen+1) * nelem, TY_CHAR) # add 1 for EOS + do j = 1, irows { + oj = oj_start + do i = 1, icols { + nret = tbagtt (itp, icp[i], j, Memc[buf], clen, + 1, nelem) + call tbaptt (otp, ocp[oi], oj, Memc[buf], clen, 1, nret) + oj = oj + oj_incr + } + oi = oi + oi_incr + } + } else { + call error (1, "invalid data type") + } + } + + call sfree (sp) +end + +# ttr_flip -- copy data from input to output +# This routine copies a table without transposing. +# irows and icols are the numbers of rows and columns in both the +# input and output tables. +# Note that if we are reversing the order of the columns (horizontal flip), +# the last column of the input table was defined first, so the flip in +# column order is taken care of by the relative order of the elements of +# the arrays icp and ocp. + +procedure ttr_flip (itp, otp, icp, ocp, irows, icols, op) + +pointer itp # i: pointer to input table struct +pointer otp # i: pointer to output table struct +pointer icp[icols] # i: array of pointers to input column descriptors +pointer ocp[ARB] # i: array of pointers to output column descriptors +int irows # i: number of rows in input table +int icols # i: number of columns in input table +int op[2] # i: mapping of (columns,rows) from input to output +#-- +int j # loop index for input row number +int oj, oj_incr # loop index and increment for output row number +errchk tbrcpy, tbrcsc + +begin + # Assign values for the beginning and increment for the loop + # on output row number. + if (op[2] > 0) { + oj = 1 + oj_incr = 1 + } else { + oj = irows + oj_incr = -1 + } + + # Copy the data from input to output. + if (op[1] > 0) { + + # Retain column order. + do j = 1, irows { + call tbrcpy (itp, otp, j, oj) + oj = oj + oj_incr + } + + } else { # op[1] < 0 + + # Reverse column order. + do j = 1, irows { + call tbrcsc (itp, otp, icp, ocp, j, oj, icols) + oj = oj + oj_incr + } + } +end |