Translate - my entry
Posted in 1993
Folks,
Well, it's not THAT slow. So I'll post it - it IS kind of cute. As always
- no warranties expressed or implied - if it blows you up - NMFP (Not my prob).
It takes about .22s to run as is (3 times). (when I had it working wrong
it was taking about 2 sec).
The extend and compact functions could have been written to 'chunk' instead of
'nibble', but supportability is pretty key here and 'chunking' adds complexity.
---------- cut here ---------------------------------------------------------
DATABASE xxxx
MAIN
DEFINE junk CHAR(512)
# test data - original
LET junk =
"SELECT * FROM table WHERE foo_field MATCHES 'XYZ*' OR foo_field IS NULL"
DISPLAY junk CLIPPED
# test data - to is shorter
CALL translate("foo_field", "fieldA", junk) RETURNING junk
DISPLAY junk CLIPPED
# test data - to is longer
CALL translate("fieldA", "foo_field", junk) RETURNING junk
DISPLAY junk CLIPPED
# test data - to is same length
CALL translate("foo_field", "abcdefghi", junk) RETURNING junk
DISPLAY junk CLIPPED
END MAIN
#############################################################################
# translate all occurences of 'from' in 'strg' to 'to'
#############################################################################
FUNCTION translate(from, to, strg)
DEFINE
from, to CHAR(20),
strg CHAR(512),
idx, f_len, t_len, s_len SMALLINT,
end_pos, diff SMALLINT
# get the lengths of all parties
LET f_len = LENGTH(from)
LET t_len = LENGTH(to)
LET s_len = LENGTH(strg)
# find the string
LET idx = 0 # can't use a FOR, length may change
WHILE idx < s_len
LET idx = idx + 1 # string index
LET end_pos = idx + f_len - 1 # end of subscript
IF from = strg[idx,end_pos] THEN
# replace it - watch out for different lengths!
LET diff = t_len - f_len
IF diff > 0 THEN # to is longer
CALL extend_strg(strg, end_pos, diff) RETURNING strg
# extend string out 'diff' length
LET end_pos = idx + t_len - 1 # get new end position
LET strg[idx,end_pos] = to # assign to into strg
LET idx = end_pos # skip down to there
END IF
IF diff = 0 THEN # same size
LET strg[idx,end_pos] = to
LET idx = end_pos
END IF
IF diff < 0 THEN # to is shorter
CALL compct_strg(strg, end_pos, diff) RETURNING strg
# compact string 'diff' length
LET end_pos = idx + t_len - 1
LET strg[idx,end_pos] = to
LET idx = end_pos
END IF
LET s_len = LENGTH(strg) # have to reset boundary condition
END IF
END WHILE
RETURN strg
END FUNCTION
#####################################################################
# extend the string in question working BACK TO end_pos
#####################################################################
FUNCTION extend_strg(strg, end_pos, diff)
DEFINE
strg CHAR(512),
end_pos, diff SMALLINT,
i, j SMALLINT
FOR i = LENGTH(strg) TO end_pos STEP -1
LET j = i + diff
LET strg[j,j] = strg[i,i]
END FOR
RETURN strg
END FUNCTION
#####################################################################
# compact the string in question working OUT FROM end_pos
#####################################################################
FUNCTION compct_strg(strg, end_pos, diff)
DEFINE
strg CHAR(512),
end_pos, diff SMALLINT,
i, j SMALLINT
FOR i = end_pos TO LENGTH(strg)
LET j = i + diff # diff is negative, remember?
LET strg[j,j] = strg[i,i]
END FOR
# still need to clip end of string
LET i = LENGTH(strg) + diff # diff is still negative
LET strg = strg[1,i]
RETURN strg
END FUNCTION
----------- and here --------------------------------------------------------
j.
_____________________________________________________________________________
Jack Parker |
Hewlett Packard, BSMC Boise, Idaho, USA| I said it expired! put a new one in!
jparker@hpbs2561.boi.hp.com |
(208) 396-5388 (W) (208) 384-1623 (H) |
_____________________________________________________________________________
Any opinions expressed herein are my own and not those of my employers.
_____________________________________________________________________________