aboutsummaryrefslogtreecommitdiff
path: root/pkg/tbtables/tbysft.x
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/tbtables/tbysft.x')
-rw-r--r--pkg/tbtables/tbysft.x211
1 files changed, 211 insertions, 0 deletions
diff --git a/pkg/tbtables/tbysft.x b/pkg/tbtables/tbysft.x
new file mode 100644
index 00000000..53c479bf
--- /dev/null
+++ b/pkg/tbtables/tbysft.x
@@ -0,0 +1,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