Re: Simplify formatting.c - Mailing list pgsql-patches
From | Bruce Momjian |
---|---|
Subject | Re: Simplify formatting.c |
Date | |
Msg-id | 200806140015.m5E0FxX02327@momjian.us Whole thread Raw |
In response to | Re: Simplify formatting.c (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: Simplify formatting.c
|
List | pgsql-patches |
Tom Lane wrote: > Euler Taveira de Oliveira <euler@timbira.com> 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 <bruce@momjian.us> 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);
pgsql-patches by date: