1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
include <error.h>
include <tbset.h>
include "tbtables.h"
include "tblerr.h"
# tbcdef -- define columns
# Define a set of columns for a table. If the table is new then it does
# not need to be open. The names in the array colname will be checked
# against the columns that have already been defined in the table, but
# the calling routine should make sure there are not any duplicate names
# within colname itself.
#
# The values in the DATATYPE array may be TY_BOOL, TY_INT, TY_SHORT,
# TY_REAL, TY_DOUBLE; for a character-type column the value should be
# a negative integer, the absolute value of which is the maximum number
# of characters for that column.
#
# If this procedure increases the space for column-descriptor pointers, the
# new size will be made DEFMAXCOLS larger than required to hold all those that
# that be defined when this routine returns.
#
# This routine may reallocate the array of pointers to column descriptors,
# and the values of TB_FILE(tp), TB_ROWLEN(tp) and TB_MAXCOLS(tp) may also
# be changed.
#
# The LENARRAY argument is the array size, or one for a scalar column.
#
# Phil Hodge, 16-Jan-1989 Flush the buffer after defining the column.
# Phil Hodge, 7-Mar-1989 Eliminate TB_MODSIZE.
# Phil Hodge, 1-May-1989 Change calling sequences of tbxwnc, tbywnc.
# Phil Hodge, 14-Jan-1992 Add option for text table type;
# call tbtchs here instead of in tbcadd.
# Phil Hodge, 29-Jul-1994 Change lendata to lenarray, and use it.
# Phil Hodge, 3-Apr-1995 Set TB_MODIFIED to true.
# Phil Hodge, 20-Jun-1995 Modify for FITS tables.
# Phil Hodge, 2-Mar-1998 Call tbscol to allow a column selector.
# Phil Hodge, 12-Sep-2000 Initialize TB_INDEF_IS_CURRENT to false.
procedure tbcdef (tp, colptr,
colname, colunits, colfmt, datatype, lenarray, numcols)
pointer tp # i: pointer to table descriptor
pointer colptr[numcols] # o: pointers to new columns
char colname[SZ_COLNAME,numcols] # i: names of columns
char colunits[SZ_COLUNITS,numcols] # i: units for columns
char colfmt[SZ_COLFMT,numcols] # i: print formats for columns
int datatype[numcols] # i: data types of columns
int lenarray[numcols] # i: number of elements for each column
int numcols # i: number of columns to be defined
#--
int ntotal # number of columns including new ones
int old_ncols # TB_NCOLS before adding new columns
int old_colused # TB_COLUSED before increasing size
int new_maxcols # new maximum number of columns
int new_colused # new value for row length used
int new_rowlen # new value for row length allocated
int dtype # SPP data type of column
int dlen # number of char used by a column in table
int larray # max (lenarray, 1)
int k # Loop index
errchk tbbaln, tbcadd, tbfdef, tbtchs, tbtflu
begin
if (TB_READONLY(tp))
call error (ER_TBREADONLY,
"can't define new columns in readonly table")
# Save current values (in case table is open).
old_ncols = TB_NCOLS(tp)
old_colused = TB_COLUSED(tp)
# Check whether columns already exist.
call tbcfnd (tp, colname, colptr, numcols)
do k = 1, numcols {
if (colptr[k] != NULL) {
call eprintf ("Warning: column `%s' already exists.\n")
call pargstr (colname[1,k])
}
}
# Make sure we're not trying to create array columns for
# a table type that doesn't support it.
if (TB_TYPE(tp) != TBL_TYPE_S_ROW && TB_TYPE(tp) != TBL_TYPE_FITS) {
do k = 1, numcols {
if (lenarray[k] > 1)
call error (1, "This table type doesn't support arrays.")
}
}
# Get the new total number of columns.
ntotal = TB_NCOLS(tp) + numcols
if (ntotal > TB_MAXCOLS(tp))
new_maxcols = ntotal + DEFMAXCOLS
else
new_maxcols = -1 # i.e. don't change current value
# Get the new row length used (actually needed only if row ordered).
new_colused = TB_COLUSED(tp)
do k = 1, numcols {
call tbbaln (datatype[k], dtype, dlen)
larray = max (1, lenarray[k])
new_colused = new_colused + dlen * larray
}
new_rowlen = max (TB_ROWLEN(tp), new_colused)
# Update the values in the table struct and, if the table is open,
# update the table size.
call tbtchs (tp, -1, new_maxcols, new_rowlen, -1)
# Create descriptors for the new columns.
# For a text table, allocate memory for the column values.
call tbcadd (tp, colptr, colname, colunits, colfmt,
datatype, lenarray, numcols)
if (TB_IS_OPEN(tp)) {
# If a column selector is in effect, add all new columns.
if (TB_COLUMN_SELECT(tp) == YES) {
do k = 1, numcols
call tbscol (tp, colptr[k])
}
# Save new descriptors in table.
if (TB_TYPE(tp) == TBL_TYPE_S_ROW) {
iferr {
call tbxwnc (tp, colptr, numcols, old_colused)
} then {
TB_NCOLS(tp) = old_ncols
TB_COLUSED(tp) = old_colused
call erract (EA_ERROR)
}
} else if (TB_TYPE(tp) == TBL_TYPE_S_COL) {
iferr {
call tbywnc (tp, colptr, numcols)
} then {
TB_NCOLS(tp) = old_ncols
TB_COLUSED(tp) = old_colused
call erract (EA_ERROR)
}
} else if (TB_TYPE(tp) == TBL_TYPE_TEXT) {
;
} else if (TB_TYPE(tp) == TBL_TYPE_FITS) {
iferr {
do k = 1, numcols
call tbfdef (tp, colptr[k])
} then {
TB_NCOLS(tp) = old_ncols
TB_COLUSED(tp) = old_colused
call erract (EA_ERROR)
}
} else {
TB_NCOLS(tp) = old_ncols
TB_COLUSED(tp) = old_colused
call error (ER_TBCORRUPTED, "tbcdef: table type is messed up")
}
call tbtflu (tp) # flush the buffer
}
TB_MODIFIED(tp) = true
TB_INDEF_IS_CURRENT(tp) = false
end
|