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
|
include "tbtables.h"
include "tblerr.h"
# tbzsft -- Z 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, 31-Jan-1992 Subroutine created.
procedure tbzsft (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
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 dtype # data type of a column
int col # loop index for column number
int ip, op # loop indexes
pointer tbcnum()
begin
nrows = TB_NROWS(tp)
# Make sure there are enough rows allocated in the table.
if (first > nrows) {
if (shift > 0) {
row2 = shift + first - 1
if (row2 > TB_ALLROWS(tp)) {
call tbtchs (tp, -1, -1, -1, row2)
}
}
return # nothing else to do
} else {
row2 = shift + nrows
if (row2 > TB_ALLROWS(tp)) {
call tbtchs (tp, -1, -1, -1, row2)
}
}
if (shift == 0)
return
# Consider the case of deleting all rows starting with FIRST.
if (nrows + shift < first) {
call tbznll (tp, first, nrows)
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
else
row1 = first
row2 = nrows
do col = 1, TB_NCOLS(tp) {
cptr = tbcnum (tp, col)
dtype = COL_DTYPE(cptr)
v = COL_OFFSET(cptr) # pointer to column values
if (dtype == TBL_TY_DOUBLE) {
if (shift < 0) {
op = first
do ip = row1, row2 {
Memd[v+op-1] = Memd[v+ip-1]
op = op + 1
}
} else { # shift > 0
op = nrows + shift
do ip = row2, row1, -1 {
Memd[v+op-1] = Memd[v+ip-1]
op = op - 1
}
}
} else if (dtype == TBL_TY_INT) {
if (shift < 0) {
op = first
do ip = row1, row2 {
Memi[v+op-1] = Memi[v+ip-1]
op = op + 1
}
} else { # shift > 0
op = nrows + shift
do ip = row2, row1, -1 {
Memi[v+op-1] = Memi[v+ip-1]
op = op - 1
}
}
} else if (dtype < 0 || dtype == TBL_TY_CHAR) {
call malloc (v, SZ_LINE, TY_CHAR)
if (shift < 0) {
op = first
do ip = row1, row2 {
call tbegtt (tp, cptr, ip, Memc[v], SZ_LINE)
call tbeptt (tp, cptr, op, Memc[v])
op = op + 1
}
} else { # shift > 0
op = nrows + shift
do ip = row2, row1, -1 {
call tbegtt (tp, cptr, ip, Memc[v], SZ_LINE)
call tbeptt (tp, cptr, op, Memc[v])
op = op - 1
}
}
call mfree (v, TY_CHAR)
} else {
call error (ER_TBCOLBADTYP,
"tbzsft: table or memory corrupted?")
}
}
# If rows were deleted, set the extra rows at end to indef,
# and change the value of TB_NROWS(tp).
if (shift < 0) {
call tbznll (tp, nrows-abs_shift+1, nrows)
TB_NROWS(tp) = max (0, nrows - abs_shift)
}
end
|