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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
include "tbtables.h"
include "tblerr.h"
# tbysft -- Y shift rows
# Shift one or more rows down (to leave a gap in the table) or up (to
# delete rows). The range of rows that is shifted is from FIRST to
# the last row in the table. Shift down if SHIFT > 0, or shift up if
# SHIFT < 0. SHIFT is the number of rows by which to shift.
#
# If SHIFT > 0 rows that are exposed by the shift are NOT set to indef.
# If SHIFT < 0 rows at the end WILL be set to indef.
# In either case the number of rows TB_NROWS(tp) will be updated.
#
# Phil Hodge, 23-Mar-1988 Subroutine created.
# Phil Hodge, 1-Apr-1993 Include short datatype; errchk tbegp[] & tbepp[].
# Phil Hodge, 29-Jul-1994 Change calling sequence of tbeoff.
# Phil Hodge, 5-Mar-1998 Replace tbytsz by tbywer.
procedure tbysft (tp, first, shift)
pointer tp # i: pointer to table descriptor
int first # i: first row to be affected by the shift
int shift # i: shift by this many rows
#--
pointer cptr # pointer to a column descriptor
pointer v # pointer to array of values
pointer vj # pointer which is incremented in loop
int abs_shift # absolute value of shift
int row1, row2 # range of rows to be copied
int nrows # number of rows written to table
int nvals # number of values in scratch array
int dtype # data type of a column
int col_width # space in char for an element in table
int col # loop index for column number
int k # loop index
long i_offset # offset in char to a table element
long o_offset # offset in char to a table element
long tbeoff()
pointer tbcnum()
errchk tbegpb, tbegpd, tbegpi, tbegps, tbegpr, tbegpt,
tbeppb, tbeppd, tbeppi, tbepps, tbeppr, tbeppt,
tbywer
begin
nrows = TB_NROWS(tp)
# Make sure there are enough rows allocated in the table.
if (first > nrows) {
if (shift > 0)
call tbywer (tp, shift+first-1)
return # nothing else to do
} else {
call tbywer (tp, shift+nrows)
}
# First consider the case of deleting all rows starting with FIRST.
if (nrows + shift < first) {
call tbynll (tp, first, nrows) # set to INDEF
TB_NROWS(tp) = max (0, first-1)
return
}
if (shift > 0)
TB_NROWS(tp) = TB_NROWS(tp) + shift
abs_shift = abs (shift)
# Rows row1:row2 will be copied to row1+shift:row2+shift.
if (shift < 0) {
row1 = first + abs_shift
row2 = nrows
} else {
row1 = first
row2 = nrows
}
nvals = row2 - row1 + 1
do col = 1, TB_NCOLS(tp) {
cptr = tbcnum (tp, col)
dtype = COL_DTYPE(cptr)
col_width = COL_LEN(cptr)
switch (dtype) {
case TY_REAL:
call malloc (v, nvals, TY_REAL)
vj = v # incremented in loop
i_offset = tbeoff (tp, cptr, row1, 1)
do k = row1, row2 {
call tbegpr (tp, cptr, i_offset, k, Memr[vj]) # get
vj = vj + 1
i_offset = i_offset + col_width
}
vj = v # incremented in loop
o_offset = tbeoff (tp, cptr, row1+shift, 1)
do k = row1+shift, row2+shift {
call tbeppr (tp, cptr, o_offset, k, Memr[vj]) # put
vj = vj + 1
o_offset = o_offset + col_width
}
call mfree (v, TY_REAL)
case TY_DOUBLE:
call malloc (v, nvals, TY_DOUBLE)
vj = v
i_offset = tbeoff (tp, cptr, row1, 1)
do k = row1, row2 {
call tbegpd (tp, cptr, i_offset, k, Memd[vj])
vj = vj + 1
i_offset = i_offset + col_width
}
vj = v
o_offset = tbeoff (tp, cptr, row1+shift, 1)
do k = row1+shift, row2+shift {
call tbeppd (tp, cptr, o_offset, k, Memd[vj])
vj = vj + 1
o_offset = o_offset + col_width
}
call mfree (v, TY_DOUBLE)
case TY_INT:
call malloc (v, nvals, TY_INT)
vj = v
i_offset = tbeoff (tp, cptr, row1, 1)
do k = row1, row2 {
call tbegpi (tp, cptr, i_offset, k, Memi[vj])
vj = vj + 1
i_offset = i_offset + col_width
}
vj = v
o_offset = tbeoff (tp, cptr, row1+shift, 1)
do k = row1+shift, row2+shift {
call tbeppi (tp, cptr, o_offset, k, Memi[vj])
vj = vj + 1
o_offset = o_offset + col_width
}
call mfree (v, TY_INT)
case TY_SHORT:
call malloc (v, nvals, TY_SHORT)
vj = v
i_offset = tbeoff (tp, cptr, row1, 1)
do k = row1, row2 {
call tbegps (tp, cptr, i_offset, k, Mems[vj])
vj = vj + 1
i_offset = i_offset + col_width
}
vj = v
o_offset = tbeoff (tp, cptr, row1+shift, 1)
do k = row1+shift, row2+shift {
call tbepps (tp, cptr, o_offset, k, Mems[vj])
vj = vj + 1
o_offset = o_offset + col_width
}
call mfree (v, TY_SHORT)
case TY_BOOL:
call malloc (v, nvals, TY_BOOL)
vj = v
i_offset = tbeoff (tp, cptr, row1, 1)
do k = row1, row2 {
call tbegpb (tp, cptr, i_offset, k, Memb[vj])
vj = vj + 1
i_offset = i_offset + col_width
}
vj = v
o_offset = tbeoff (tp, cptr, row1+shift, 1)
do k = row1+shift, row2+shift {
call tbeppb (tp, cptr, o_offset, k, Memb[vj])
vj = vj + 1
o_offset = o_offset + col_width
}
call mfree (v, TY_BOOL)
default:
if (dtype >= 0 && dtype != TY_CHAR)
call error (ER_TBCOLBADTYP,
"tbysft: table or memory corrupted?")
call malloc (v, SZ_LINE, TY_CHAR)
if (shift < 0) {
i_offset = tbeoff (tp, cptr, row1, 1)
o_offset = tbeoff (tp, cptr, row1-abs_shift, 1)
do k = row1, row2 {
call tbegpt (tp, cptr, i_offset, k, Memc[v], SZ_LINE)
call tbeppt (tp, cptr, o_offset, k, Memc[v])
i_offset = i_offset + col_width
o_offset = o_offset + col_width
}
} else {
i_offset = tbeoff (tp, cptr, row2, 1)
o_offset = tbeoff (tp, cptr, row2+shift, 1)
# (actually, it's the offsets that count; k is ignored)
do k = row2+shift, row1+shift, -1 {
call tbegpt (tp, cptr, i_offset, k, Memc[v], SZ_LINE)
call tbeppt (tp, cptr, o_offset, k, Memc[v])
i_offset = i_offset - col_width
o_offset = o_offset - col_width
}
}
call mfree (v, TY_CHAR)
}
}
# If rows were deleted, set the extra rows at end to indef,
# and change the value of TB_NROWS(tp).
if (shift < 0) {
call tbynll (tp, nrows-abs_shift+1, nrows)
TB_NROWS(tp) = max (0, nrows - abs_shift)
}
end
|