The tbrgtT and tbcgtT routines return a boolean array that indicates whether the table elements gotten are undefined. A true value means the table element is undefined. The tbegtT routine returns the data type-specific INDEF
value when the table element is undefined. When writing values into a table, values may be set to undefined by calling tbrudf. If a row exists, but no value has ever been written to a particular column in that row, the element at that row and column will automatically be undefined; that is, it is not necessary to call tbrudf. A row exists if a value has been put into any column in that row or into a subsequent row (larger row number).
Table E.5: Table Get and Put Procedures.
Example E.2 gets two values from each row of a table and copies them to another table if neither value is undefined. A double-precision buffer is used so that data of any numerical type will be copied without loss of precision.
include <tbset.h> define NCOLS 2 # number of columns to get procedure test() pointer sp # stack pointer pointer intable, outtable # scratch for table names pointer ira, idec # scratch for arrays of input values pointer ora, odec # scratch for arrays of output values pointer ra_flag # scratch for array of null flags pointer dec_flag # scratch for array of null flags char cname[SZ_COLNAME,NCOLS] # column names pointer itp, otp # pointers to table descriptors pointer icp[NCOLS] # pointers to column descriptors in input pointer ocp[NCOLS] # pointers to column descriptors in output int inrows, onrows # number of rows in input, output tables int irow # loop index for row number in input table int orow # row number in output table int i # loop index bool nullflag[NCOLS] # null flags for getting info from a row bool bad # true if any element of nullflag is true double value[NCOLS] # values gotten from a table pointer tbtopn() int tbpsta() begin # Allocate scratch space for table names. We'll allocate space # for column values later, after we know the size of the table. call smark (sp) call salloc (intable, SZ_FNAME, TY_CHAR) call salloc (outtable, SZ_FNAME, TY_CHAR) # Get table names. call clgstr ("intable", Memc[intable], SZ_FNAME) call clgstr ("outtable", Memc[outtable], SZ_FNAME) # Get column names. call clgstr ("ra_col", cname[1,1], SZ_COLNAME) call clgstr ("dec_col", cname[1,2], SZ_COLNAME) # Open input table. itp = tbtopn (Memc[intable], READ_ONLY, NULL) # Find columns in input table. Check if they were found. call tbcfnd (itp, cname, icp, NCOLS) if (icp[1] == NULL || icp[2] == NULL) { call tbtclo (itp) call error (1, "column not found") }
# Create an output table with the same columns as the input table. otp = tbtopn (Memc[outtable], NEW_COPY, itp) call tbtcre (otp) # Copy header parameters from input to output. call tbhcal (itp, otp) # Find columns in output table. They will be there since they were # in the input table. call tbcfnd (otp, cname, ocp, NCOLS) # There will be fewer rows in the output table if the columns # we're interested in contain undefined elements. inrows = tbpsta (itp, TBL_NROWS) # Here are three different ways of copying the values. # 1. Copy element by element. orow = 0 do irow = 1, inrows { call tbegtd (itp, icp[1], irow, value[1]) call tbegtd (itp, icp[2], irow, value[2]) if (!IS_INDEFD(value[1]) && !IS_INDEFD(value[2])) { orow = orow + 1 call tbeptd (otp, ocp[1], orow, value[1]) call tbeptd (otp, ocp[2], orow, value[2]) } } # 2. Use the get-row and put-row routines. This will copy # any number of columns, one row at a time. orow = 0 do irow = 1, inrows { call tbrgtd (itp, icp, value, nullflag, NCOLS, irow) bad = false do i = 1, NCOLS if (nullflag[i]) bad = true if (!bad) { orow = orow + 1 call tbrptd (otp, ocp, value, NCOLS, orow) } }
# 3. Use the get-column and put-column routines. call salloc (ira, inrows, TY_DOUBLE) call salloc (idec, inrows, TY_DOUBLE) call salloc (ra_flag, inrows, TY_BOOL) call salloc (dec_flag, inrows, TY_BOOL) call salloc (ora, inrows, TY_DOUBLE) # possibly more than we need call salloc (odec, inrows, TY_DOUBLE) call tbcgtd (itp, icp[1], Memd[ira], Memb[ra_flag], 1, inrows) call tbcgtd (itp, icp[2], Memd[idec], Memb[dec_flag], 1, inrows) # Note that irow and orow are zero indexed in this loop. orow = -1 do irow = 0, inrows-1 { if (!Memb[ra_flag+irow] && !Memb[dec_flag+irow]) { orow = orow + 1 Memd[ora+orow] = Memd[ira+irow] Memd[odec+orow] = Memd[idec+irow] } } onrows = orow + 1 # number of rows in output table if (orow > 0) { call tbcptd (otp, ocp[1], Memd[ora], 1, onrows) call tbcptd (otp, ocp[2], Memd[odec], 1, onrows) } # Done. Three times, even. call tbtclo (itp) call tbtclo (otp) call sfree (sp) end
Generated with CERN WebMaker