Tom Lane wrote:
> Euler Taveira de Oliveira <[EMAIL PROTECTED]> writes:
> > Tom Lane wrote:
> >> Also, it seems a bit inconsistent to be relying on
> >> oracle_compat.c for upper/lower but not initcap.
> >>
> > I saw this inconsistence while I'm doing the patch. What about moving
> > that upper/lower/initcap and wcs* code to another file. pg_locale.c?
>
> That doesn't seem a particularly appropriate place for them. pg_locale
> is about dealing with the locale state, not about doing actual
> operations based on the locale data.
>
> I was just thinking of having oracle_compat expose an initcap routine.
You mean like the attached?
I moved str_initcap() over into oracle_compat.c and then had initcap()
convert to/from TEXT to call it. The code is a little weird because
str_initcap() needs to convert to text to use texttowcs(), so in
multibyte encodings initcap converts the string to text, then to char,
then to text to call texttowcs(). I didn't see a cleaner way to do
this.
--
Bruce Momjian <[EMAIL PROTECTED]> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ If your life is a hard drive, Christ can be your backup. +
Index: src/backend/utils/adt/formatting.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v
retrieving revision 1.141
diff -c -c -r1.141 formatting.c
*** src/backend/utils/adt/formatting.c 20 May 2008 01:41:02 -0000 1.141
--- src/backend/utils/adt/formatting.c 13 Jun 2008 22:01:18 -0000
***************
*** 927,933 ****
static int strdigits_len(char *str);
static char *str_toupper(char *buff);
static char *str_tolower(char *buff);
- static char *str_initcap(char *buff);
static int seq_search(char *name, char **array, int type, int max, int *len);
static void do_to_timestamp(text *date_txt, text *fmt,
--- 927,932 ----
***************
*** 1484,1549 ****
}
/* ----------
- * wide-character-aware initcap function
- * ----------
- */
- static char *
- str_initcap(char *buff)
- {
- char *result;
- bool wasalnum = false;
-
- if (!buff)
- return NULL;
-
- #ifdef USE_WIDE_UPPER_LOWER
- if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
- {
- wchar_t *workspace;
- text *in_text;
- text *out_text;
- int i;
-
- in_text = cstring_to_text(buff);
- workspace = texttowcs(in_text);
-
- for (i = 0; workspace[i] != 0; i++)
- {
- if (wasalnum)
- workspace[i] = towlower(workspace[i]);
- else
- workspace[i] = towupper(workspace[i]);
- wasalnum = iswalnum(workspace[i]);
- }
-
- out_text = wcstotext(workspace, i);
- result = text_to_cstring(out_text);
-
- pfree(workspace);
- pfree(in_text);
- pfree(out_text);
- }
- else
- #endif /* USE_WIDE_UPPER_LOWER */
- {
- char *p;
-
- result = pstrdup(buff);
-
- for (p = result; *p; p++)
- {
- if (wasalnum)
- *p = pg_tolower((unsigned char) *p);
- else
- *p = pg_toupper((unsigned char) *p);
- wasalnum = isalnum((unsigned char) *p);
- }
- }
-
- return result;
- }
-
- /* ----------
* Sequential search with to upper/lower conversion
* ----------
*/
--- 1483,1488 ----
Index: src/backend/utils/adt/oracle_compat.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v
retrieving revision 1.79
diff -c -c -r1.79 oracle_compat.c
*** src/backend/utils/adt/oracle_compat.c 19 May 2008 18:08:16 -0000 1.79
--- src/backend/utils/adt/oracle_compat.c 13 Jun 2008 22:01:18 -0000
***************
*** 471,478 ****
Datum
initcap(PG_FUNCTION_ARGS)
{
! #ifdef USE_WIDE_UPPER_LOWER
/*
* Use wide char code only when max encoding length > 1 and ctype != C.
* Some operating systems fail with multi-byte encodings and a C locale.
--- 471,496 ----
Datum
initcap(PG_FUNCTION_ARGS)
{
! text *string = PG_GETARG_TEXT_PP(0);
! char *str2;
!
! str2 = str_initcap(DatumGetCString(string));
! string = cstring_to_text(str2);
! pfree(str2);
! PG_RETURN_TEXT_P(string);
! }
!
+ char *
+ str_initcap(char *str)
+ {
+ char *result;
+ int wasalnum = 0;
+
+ if (!str)
+ return NULL;
+
+ #ifdef USE_WIDE_UPPER_LOWER
/*
* Use wide char code only when max encoding length > 1 and ctype != C.
* Some operating systems fail with multi-byte encodings and a C locale.
***************
*** 480,492 ****
*/
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
{
- text *string = PG_GETARG_TEXT_PP(0);
- text *result;
wchar_t *workspace;
! int wasalnum = 0;
int i;
! workspace = texttowcs(string);
for (i = 0; workspace[i] != 0; i++)
{
--- 498,510 ----
*/
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
{
wchar_t *workspace;
! text *in_text;
! text *out_text;
int i;
! in_text = cstring_to_text(str);
! workspace = texttowcs(in_text);
for (i = 0; workspace[i] != 0; i++)
{
***************
*** 497,533 ****
wasalnum = iswalnum(workspace[i]);
}
! result = wcstotext(workspace, i);
pfree(workspace);
! PG_RETURN_TEXT_P(result);
}
else
#endif /* USE_WIDE_UPPER_LOWER */
{
- text *string = PG_GETARG_TEXT_P_COPY(0);
- int wasalnum = 0;
char *ptr;
- int m;
/*
* Since we copied the string, we can scribble directly on the value
*/
! ptr = VARDATA(string);
! m = VARSIZE(string) - VARHDRSZ;
!
! while (m-- > 0)
{
if (wasalnum)
*ptr = tolower((unsigned char) *ptr);
else
*ptr = toupper((unsigned char) *ptr);
wasalnum = isalnum((unsigned char) *ptr);
- ptr++;
}
! PG_RETURN_TEXT_P(string);
}
}
--- 515,548 ----
wasalnum = iswalnum(workspace[i]);
}
! out_text = wcstotext(workspace, i);
! result = text_to_cstring(out_text);
pfree(workspace);
+ pfree(in_text);
+ pfree(out_text);
! return result;
}
else
#endif /* USE_WIDE_UPPER_LOWER */
{
char *ptr;
+ result = pstrdup(str);
/*
* Since we copied the string, we can scribble directly on the value
*/
! for (ptr = result; *ptr; ptr++)
{
if (wasalnum)
*ptr = tolower((unsigned char) *ptr);
else
*ptr = toupper((unsigned char) *ptr);
wasalnum = isalnum((unsigned char) *ptr);
}
! return result;
}
}
Index: src/include/utils/builtins.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/utils/builtins.h,v
retrieving revision 1.316
diff -c -c -r1.316 builtins.h
*** src/include/utils/builtins.h 27 May 2008 00:13:09 -0000 1.316
--- src/include/utils/builtins.h 13 Jun 2008 22:01:19 -0000
***************
*** 727,732 ****
--- 727,733 ----
extern Datum lower(PG_FUNCTION_ARGS);
extern Datum upper(PG_FUNCTION_ARGS);
extern Datum initcap(PG_FUNCTION_ARGS);
+ extern char *str_initcap(char *str);
extern Datum lpad(PG_FUNCTION_ARGS);
extern Datum rpad(PG_FUNCTION_ARGS);
extern Datum btrim(PG_FUNCTION_ARGS);
--
Sent via pgsql-patches mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches