Commit 77f48853 authored by Tom Lane's avatar Tom Lane

Fix busted TRANSLATE() code --- it coredumped due to pfree()'ing the

wrong pointer.
parent 795878d2
/* /*
* Edmund Mergl <E.Mergl@bawue.de> * Edmund Mergl <E.Mergl@bawue.de>
* *
* $Id: oracle_compat.c,v 1.21 2000/03/14 23:06:37 thomas Exp $ * $Id: oracle_compat.c,v 1.22 2000/03/15 17:24:18 tgl Exp $
* *
*/ */
...@@ -500,64 +500,76 @@ substr(text *string, int4 m, int4 n) ...@@ -500,64 +500,76 @@ substr(text *string, int4 m, int4 n)
* *
* Purpose: * Purpose:
* *
* Returns string after replacing all occurences of from with * Returns string after replacing all occurrences of characters in from
* the corresponding character in to. TRANSLATE will not remove * with the corresponding character in to. If from is longer than to,
* characters. * occurrences of the extra characters in from are deleted.
* Modified to work with strings rather than single character * Improved by Edwin Ramirez <ramirez@doc.mssm.edu>.
* for the substitution arguments.
* Modifications from Edwin Ramirez <ramirez@doc.mssm.edu>.
* *
********************************************************************/ ********************************************************************/
text * text *
translate(text *string, text *from, text *to) translate(text *string, text *from, text *to)
{ {
text *ret; text *result;
char *ptr_ret, *from_ptr, *to_ptr; char *from_ptr, *to_ptr;
char *source, *target, *temp, rep; char *source, *target;
int m, fromlen, tolen, retlen, i; int m, fromlen, tolen, retlen, i;
if ((string == (text *) NULL) || if (string == (text *) NULL ||
((m = VARSIZE(string) - VARHDRSZ) <= 0)) from == (text *) NULL ||
return string; to == (text *) NULL)
return (text *) NULL;
target = (char *) palloc(VARSIZE(string) - VARHDRSZ); if ((m = VARSIZE(string) - VARHDRSZ) <= 0)
source = VARDATA(string); return string;
temp = target;
fromlen = VARSIZE(from) - VARHDRSZ; fromlen = VARSIZE(from) - VARHDRSZ;
from_ptr = VARDATA(from); from_ptr = VARDATA(from);
tolen = VARSIZE(to) - VARHDRSZ; tolen = VARSIZE(to) - VARHDRSZ;
to_ptr = VARDATA(to); to_ptr = VARDATA(to);
result = (text *) palloc(VARSIZE(string));
source = VARDATA(string);
target = VARDATA(result);
retlen = 0; retlen = 0;
while (m--)
while (m-- > 0)
{ {
rep = *source; char rep = *source++;
for(i=0;i<fromlen;i++) {
if(from_ptr[i] == *source) { for (i = 0; i < fromlen; i++)
if(i < tolen) { {
rep = to_ptr[i]; if (from_ptr[i] == rep)
} else {
rep = 0;
}
break; break;
}
} }
if(rep != 0) { if (i < fromlen)
*target++ = rep; {
retlen++; if (i < tolen)
{
/* substitute */
*target++ = to_ptr[i];
retlen++;
}
else
{
/* discard */
}
}
else
{
/* no match, so copy */
*target++ = rep;
retlen++;
} }
source++;
} }
ret = (text *) palloc(retlen + VARHDRSZ); VARSIZE(result) = retlen + VARHDRSZ;
VARSIZE(ret) = retlen + VARHDRSZ; /*
ptr_ret = VARDATA(ret); * There may be some wasted space in the result if deletions occurred,
for(i=0;i<retlen;i++) { * but it's not worth reallocating it; the function result probably
*ptr_ret++ = temp[i]; * won't live long anyway.
} */
pfree(target);
return ret;
}
/* EOF */ return result;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment