aboutsummaryrefslogtreecommitdiff
path: root/pkg/tbtables/tbysft.x
blob: 53c479bfdc1df561e14be34b88398391038021cf (plain) (blame)
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