11/*
22 *Edmund Mergl <E.Mergl@bawue.de>
33 *
4- *$Header: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v 1.29 2000/12/03 20:45:36 tgl Exp $
4+ *$Header: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v 1.30 2000/12/07 23:22:56 tgl Exp $
55 *
66 */
77
8- #include <ctype.h>
9-
108#include "postgres.h"
119
10+ #include <ctype.h>
11+
1212#include "utils/builtins.h"
1313
1414
@@ -140,7 +140,8 @@ initcap(PG_FUNCTION_ARGS)
140140 * Purpose:
141141 *
142142 * Returns string1, left-padded to length len with the sequence of
143- * characters in string2.
143+ * characters in string2. If len is less than the length of string1,
144+ * instead truncate (on the right) to len.
144145 *
145146 ********************************************************************/
146147
@@ -153,31 +154,49 @@ lpad(PG_FUNCTION_ARGS)
153154text * ret ;
154155char * ptr1 ,
155156* ptr2 ,
157+ * ptr2end ,
156158* ptr_ret ;
157159int m ,
158- n ;
160+ s1len ,
161+ s2len ;
162+
163+ /* Negative len is silently taken as zero */
164+ if (len < 0 )
165+ len = 0 ;
166+
167+ s1len = VARSIZE (string1 )- VARHDRSZ ;
168+ if (s1len < 0 )
169+ s1len = 0 ;/* shouldn't happen */
170+
171+ s2len = VARSIZE (string2 )- VARHDRSZ ;
172+ if (s2len < 0 )
173+ s2len = 0 ;/* shouldn't happen */
159174
160- if (((VARSIZE (string1 )- VARHDRSZ )< 0 )||
161- ((m = len - (VARSIZE (string1 )- VARHDRSZ )) <=0 )||
162- ((VARSIZE (string2 )- VARHDRSZ ) <=0 ))
163- PG_RETURN_TEXT_P (string1 );
175+ if (s1len > len )
176+ s1len = len ;/* truncate string1 to len chars */
177+
178+ if (s2len <=0 )
179+ len = s1len ;/* nothing to pad with, so don't pad */
164180
165181ret = (text * )palloc (VARHDRSZ + len );
166182VARATT_SIZEP (ret )= VARHDRSZ + len ;
167183
184+ m = len - s1len ;
185+
168186ptr2 = VARDATA (string2 );
187+ ptr2end = ptr2 + s2len ;
169188ptr_ret = VARDATA (ret );
170189
171190while (m -- )
172191{
173- * ptr_ret ++ = * ptr2 ;
174- ptr2 = (ptr2 == VARDATA (string2 )+ VARSIZE (string2 )- VARHDRSZ - 1 ) ?VARDATA (string2 ) :++ ptr2 ;
192+ * ptr_ret ++ = * ptr2 ++ ;
193+ if (ptr2 == ptr2end )/* wrap around at end of s2 */
194+ ptr2 = VARDATA (string2 );
175195}
176196
177- n = VARSIZE (string1 )- VARHDRSZ ;
178197ptr1 = VARDATA (string1 );
179198
180- while (n -- )
199+ while (s1len -- )
181200* ptr_ret ++ = * ptr1 ++ ;
182201
183202PG_RETURN_TEXT_P (ret );
@@ -195,7 +214,8 @@ lpad(PG_FUNCTION_ARGS)
195214 * Purpose:
196215 *
197216 * Returns string1, right-padded to length len with the sequence of
198- * characters in string2.
217+ * characters in string2. If len is less than the length of string1,
218+ * instead truncate (on the right) to len.
199219 *
200220 ********************************************************************/
201221
@@ -208,31 +228,49 @@ rpad(PG_FUNCTION_ARGS)
208228text * ret ;
209229char * ptr1 ,
210230* ptr2 ,
231+ * ptr2end ,
211232* ptr_ret ;
212233int m ,
213- n ;
234+ s1len ,
235+ s2len ;
236+
237+ /* Negative len is silently taken as zero */
238+ if (len < 0 )
239+ len = 0 ;
240+
241+ s1len = VARSIZE (string1 )- VARHDRSZ ;
242+ if (s1len < 0 )
243+ s1len = 0 ;/* shouldn't happen */
214244
215- if (((VARSIZE (string1 )- VARHDRSZ )< 0 )||
216- ((m = len - (VARSIZE (string1 )- VARHDRSZ )) <=0 )||
217- ((VARSIZE (string2 )- VARHDRSZ ) <=0 ))
218- PG_RETURN_TEXT_P (string1 );
245+ s2len = VARSIZE (string2 )- VARHDRSZ ;
246+ if (s2len < 0 )
247+ s2len = 0 ;/* shouldn't happen */
248+
249+ if (s1len > len )
250+ s1len = len ;/* truncate string1 to len chars */
251+
252+ if (s2len <=0 )
253+ len = s1len ;/* nothing to pad with, so don't pad */
219254
220255ret = (text * )palloc (VARHDRSZ + len );
221256VARATT_SIZEP (ret )= VARHDRSZ + len ;
222257
223- n = VARSIZE (string1 )- VARHDRSZ ;
258+ m = len - s1len ;
259+
224260ptr1 = VARDATA (string1 );
225261ptr_ret = VARDATA (ret );
226262
227- while (n -- )
263+ while (s1len -- )
228264* ptr_ret ++ = * ptr1 ++ ;
229265
230266ptr2 = VARDATA (string2 );
267+ ptr2end = ptr2 + s2len ;
231268
232269while (m -- )
233270{
234- * ptr_ret ++ = * ptr2 ;
235- ptr2 = (ptr2 == VARDATA (string2 )+ VARSIZE (string2 )- VARHDRSZ - 1 ) ?VARDATA (string2 ) :++ ptr2 ;
271+ * ptr_ret ++ = * ptr2 ++ ;
272+ if (ptr2 == ptr2end )/* wrap around at end of s2 */
273+ ptr2 = VARDATA (string2 );
236274}
237275
238276PG_RETURN_TEXT_P (ret );