Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f6ec743

Browse files
committed
Merge duplicate upper/lower/initcap() routines in oracle_compat.c and
formatting.c to use common code; remove duplicate functions and support routines that are no longer needed.
1 parent eeee069 commit f6ec743

File tree

3 files changed

+144
-475
lines changed

3 files changed

+144
-475
lines changed

src/backend/utils/adt/formatting.c

+116-52
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* -----------------------------------------------------------------------
22
* formatting.c
33
*
4-
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.142 2008/06/17 16:09:06 momjian Exp $
4+
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.143 2008/06/23 19:27:19 momjian Exp $
55
*
66
*
77
* Portions Copyright (c) 1999-2008, PostgreSQL Global Development Group
@@ -925,9 +925,6 @@ static char *get_th(char *num, int type);
925925
static char *str_numth(char *dest, char *num, int type);
926926
static int strspace_len(char *str);
927927
static int strdigits_len(char *str);
928-
static char *str_toupper(char *buff);
929-
static char *str_tolower(char *buff);
930-
static char *str_initcap(char *buff);
931928

932929
static int seq_search(char *name, char **array, int type, int max, int *len);
933930
static void do_to_timestamp(text *date_txt, text *fmt,
@@ -1424,12 +1421,24 @@ str_numth(char *dest, char *num, int type)
14241421
return dest;
14251422
}
14261423

1424+
/*
1425+
* If the system provides the needed functions for wide-character manipulation
1426+
* (which are all standardized by C99), then we implement upper/lower/initcap
1427+
* using wide-character functions, if necessary. Otherwise we use the
1428+
* traditional <ctype.h> functions, which of course will not work as desired
1429+
* in multibyte character sets. Note that in either case we are effectively
1430+
* assuming that the database character encoding matches the encoding implied
1431+
* by LC_CTYPE.
1432+
*/
1433+
14271434
/* ----------
1428-
* Convert string to upper case. It is designed to be multibyte-aware.
1435+
* wide-character-aware lower function
1436+
* We pass the number of bytes so we can pass varlena and char*
1437+
* to this function.
14291438
* ----------
14301439
*/
1431-
static char *
1432-
str_toupper(char *buff)
1440+
char *
1441+
str_tolower(char *buff, size_t nbytes)
14331442
{
14341443
char *result;
14351444

@@ -1438,27 +1447,46 @@ str_toupper(char *buff)
14381447

14391448
#ifdef USE_WIDE_UPPER_LOWER
14401449
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
1441-
result = wstring_upper(buff);
1450+
{
1451+
wchar_t *workspace;
1452+
int curr_char = 0;
1453+
1454+
/* Output workspace cannot have more codes than input bytes */
1455+
workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1456+
1457+
char2wchar(workspace, nbytes + 1, buff, nbytes + 1);
1458+
1459+
for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1460+
workspace[curr_char] = towlower(workspace[curr_char]);
1461+
1462+
/* Make result large enough; case change might change number of bytes */
1463+
result = palloc(curr_char * MB_CUR_MAX + 1);
1464+
1465+
wchar2char(result, workspace, curr_char * MB_CUR_MAX + 1);
1466+
pfree(workspace);
1467+
}
14421468
else
14431469
#endif /* USE_WIDE_UPPER_LOWER */
14441470
{
14451471
char *p;
14461472

1447-
result = pstrdup(buff);
1473+
result = pnstrdup(buff, nbytes);
14481474

14491475
for (p = result; *p; p++)
1450-
*p = pg_toupper((unsigned char) *p);
1476+
*p = pg_tolower((unsigned char) *p);
14511477
}
14521478

14531479
return result;
14541480
}
14551481

14561482
/* ----------
1457-
* Convert string to lower case. It is designed to be multibyte-aware.
1483+
* wide-character-aware upper function
1484+
* We pass the number of bytes so we can pass varlena and char*
1485+
* to this function.
14581486
* ----------
14591487
*/
1460-
static char *
1461-
str_tolower(char *buff)
1488+
char *
1489+
str_toupper(char *buff, size_t nbytes)
14621490
{
14631491
char *result;
14641492

@@ -1467,27 +1495,46 @@ str_tolower(char *buff)
14671495

14681496
#ifdef USE_WIDE_UPPER_LOWER
14691497
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
1470-
result = wstring_lower(buff);
1498+
{
1499+
wchar_t *workspace;
1500+
int curr_char = 0;
1501+
1502+
/* Output workspace cannot have more codes than input bytes */
1503+
workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1504+
1505+
char2wchar(workspace, nbytes + 1, buff, nbytes + 1);
1506+
1507+
for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1508+
workspace[curr_char] = towupper(workspace[curr_char]);
1509+
1510+
/* Make result large enough; case change might change number of bytes */
1511+
result = palloc(curr_char * MB_CUR_MAX + 1);
1512+
1513+
wchar2char(result, workspace, curr_char * MB_CUR_MAX + 1);
1514+
pfree(workspace);
1515+
}
14711516
else
14721517
#endif /* USE_WIDE_UPPER_LOWER */
14731518
{
14741519
char *p;
14751520

1476-
result = pstrdup(buff);
1521+
result = pnstrdup(buff, nbytes);
14771522

14781523
for (p = result; *p; p++)
1479-
*p = pg_tolower((unsigned char) *p);
1524+
*p = pg_toupper((unsigned char) *p);
14801525
}
14811526

14821527
return result;
14831528
}
1484-
1529+
14851530
/* ----------
14861531
* wide-character-aware initcap function
1532+
* We pass the number of bytes so we can pass varlena and char*
1533+
* to this function.
14871534
* ----------
14881535
*/
1489-
static char *
1490-
str_initcap(char *buff)
1536+
char *
1537+
str_initcap(char *buff, size_t nbytes)
14911538
{
14921539
char *result;
14931540
bool wasalnum = false;
@@ -1499,35 +1546,34 @@ str_initcap(char *buff)
14991546
if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
15001547
{
15011548
wchar_t *workspace;
1502-
text *in_text;
1503-
text *out_text;
1504-
int i;
1549+
int curr_char = 0;
1550+
1551+
/* Output workspace cannot have more codes than input bytes */
1552+
workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
15051553

1506-
in_text = cstring_to_text(buff);
1507-
workspace = texttowcs(in_text);
1554+
char2wchar(workspace, nbytes + 1, buff, nbytes + 1);
15081555

1509-
for (i = 0; workspace[i] != 0; i++)
1556+
for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
15101557
{
15111558
if (wasalnum)
1512-
workspace[i] = towlower(workspace[i]);
1559+
workspace[curr_char] = towlower(workspace[curr_char]);
15131560
else
1514-
workspace[i] = towupper(workspace[i]);
1515-
wasalnum = iswalnum(workspace[i]);
1561+
workspace[curr_char] = towupper(workspace[curr_char]);
1562+
wasalnum = iswalnum(workspace[curr_char]);
15161563
}
15171564

1518-
out_text = wcstotext(workspace, i);
1519-
result = text_to_cstring(out_text);
1565+
/* Make result large enough; case change might change number of bytes */
1566+
result = palloc(curr_char * MB_CUR_MAX + 1);
15201567

1568+
wchar2char(result, workspace, curr_char * MB_CUR_MAX + 1);
15211569
pfree(workspace);
1522-
pfree(in_text);
1523-
pfree(out_text);
15241570
}
15251571
else
15261572
#endif /* USE_WIDE_UPPER_LOWER */
15271573
{
15281574
char *p;
15291575

1530-
result = pstrdup(buff);
1576+
result = pnstrdup(buff, nbytes);
15311577

15321578
for (p = result; *p; p++)
15331579
{
@@ -1851,7 +1897,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
18511897
{
18521898
char *p = pstrdup(tmtcTzn(in));
18531899

1854-
strcpy(s, str_tolower(p));
1900+
strcpy(s, str_tolower(p, strlen(p)));
18551901
pfree(p);
18561902
s += strlen(s);
18571903
}
@@ -1893,11 +1939,13 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
18931939
if (!tm->tm_mon)
18941940
break;
18951941
if (S_TM(n->suffix))
1896-
strcpy(s, str_toupper(localized_full_months[tm->tm_mon - 1]));
1942+
strcpy(s, str_toupper(localized_full_months[tm->tm_mon - 1],
1943+
strlen(localized_full_months[tm->tm_mon - 1])));
18971944
else
18981945
{
18991946
strcpy(workbuff, months_full[tm->tm_mon - 1]);
1900-
sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9, str_toupper(workbuff));
1947+
sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
1948+
str_toupper(workbuff, strlen(workbuff)));
19011949
}
19021950
s += strlen(s);
19031951
break;
@@ -1906,7 +1954,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
19061954
if (!tm->tm_mon)
19071955
break;
19081956
if (S_TM(n->suffix))
1909-
strcpy(s, str_initcap(localized_full_months[tm->tm_mon - 1]));
1957+
strcpy(s, str_initcap(localized_full_months[tm->tm_mon - 1],
1958+
strlen(localized_full_months[tm->tm_mon - 1])));
19101959
else
19111960
sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9, months_full[tm->tm_mon - 1]);
19121961
s += strlen(s);
@@ -1916,7 +1965,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
19161965
if (!tm->tm_mon)
19171966
break;
19181967
if (S_TM(n->suffix))
1919-
strcpy(s, str_tolower(localized_full_months[tm->tm_mon - 1]));
1968+
strcpy(s, str_tolower(localized_full_months[tm->tm_mon - 1],
1969+
strlen(localized_full_months[tm->tm_mon - 1])));
19201970
else
19211971
{
19221972
sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9, months_full[tm->tm_mon - 1]);
@@ -1929,17 +1979,20 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
19291979
if (!tm->tm_mon)
19301980
break;
19311981
if (S_TM(n->suffix))
1932-
strcpy(s, str_toupper(localized_abbrev_months[tm->tm_mon - 1]));
1982+
strcpy(s, str_toupper(localized_abbrev_months[tm->tm_mon - 1],
1983+
strlen(localized_abbrev_months[tm->tm_mon - 1])));
19331984
else
1934-
strcpy(s, str_toupper(months[tm->tm_mon - 1]));
1985+
strcpy(s, str_toupper(months[tm->tm_mon - 1],
1986+
strlen(months[tm->tm_mon - 1])));
19351987
s += strlen(s);
19361988
break;
19371989
case DCH_Mon:
19381990
INVALID_FOR_INTERVAL;
19391991
if (!tm->tm_mon)
19401992
break;
19411993
if (S_TM(n->suffix))
1942-
strcpy(s, str_initcap(localized_abbrev_months[tm->tm_mon - 1]));
1994+
strcpy(s, str_initcap(localized_abbrev_months[tm->tm_mon - 1],
1995+
strlen(localized_abbrev_months[tm->tm_mon - 1])));
19431996
else
19441997
strcpy(s, months[tm->tm_mon - 1]);
19451998
s += strlen(s);
@@ -1949,7 +2002,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
19492002
if (!tm->tm_mon)
19502003
break;
19512004
if (S_TM(n->suffix))
1952-
strcpy(s, str_tolower(localized_abbrev_months[tm->tm_mon - 1]));
2005+
strcpy(s, str_tolower(localized_abbrev_months[tm->tm_mon - 1],
2006+
strlen(localized_abbrev_months[tm->tm_mon - 1])));
19532007
else
19542008
{
19552009
strcpy(s, months[tm->tm_mon - 1]);
@@ -1966,26 +2020,30 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
19662020
case DCH_DAY:
19672021
INVALID_FOR_INTERVAL;
19682022
if (S_TM(n->suffix))
1969-
strcpy(s, str_toupper(localized_full_days[tm->tm_wday]));
2023+
strcpy(s, str_toupper(localized_full_days[tm->tm_wday],
2024+
strlen(localized_full_days[tm->tm_wday])));
19702025
else
19712026
{
19722027
strcpy(workbuff, days[tm->tm_wday]);
1973-
sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9, str_toupper(workbuff));
2028+
sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
2029+
str_toupper(workbuff, strlen(workbuff)));
19742030
}
19752031
s += strlen(s);
19762032
break;
19772033
case DCH_Day:
19782034
INVALID_FOR_INTERVAL;
19792035
if (S_TM(n->suffix))
1980-
strcpy(s, str_initcap(localized_full_days[tm->tm_wday]));
2036+
strcpy(s, str_initcap(localized_full_days[tm->tm_wday],
2037+
strlen(localized_full_days[tm->tm_wday])));
19812038
else
19822039
sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9, days[tm->tm_wday]);
19832040
s += strlen(s);
19842041
break;
19852042
case DCH_day:
19862043
INVALID_FOR_INTERVAL;
19872044
if (S_TM(n->suffix))
1988-
strcpy(s, str_tolower(localized_full_days[tm->tm_wday]));
2045+
strcpy(s, str_tolower(localized_full_days[tm->tm_wday],
2046+
strlen(localized_full_days[tm->tm_wday])));
19892047
else
19902048
{
19912049
sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9, days[tm->tm_wday]);
@@ -1996,23 +2054,27 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out)
19962054
case DCH_DY:
19972055
INVALID_FOR_INTERVAL;
19982056
if (S_TM(n->suffix))
1999-
strcpy(s, str_toupper(localized_abbrev_days[tm->tm_wday]));
2057+
strcpy(s, str_toupper(localized_abbrev_days[tm->tm_wday],
2058+
strlen(localized_abbrev_days[tm->tm_wday])));
20002059
else
2001-
strcpy(s, str_toupper(days_short[tm->tm_wday]));
2060+
strcpy(s, str_toupper(days_short[tm->tm_wday],
2061+
strlen(days_short[tm->tm_wday])));
20022062
s += strlen(s);
20032063
break;
20042064
case DCH_Dy:
20052065
INVALID_FOR_INTERVAL;
20062066
if (S_TM(n->suffix))
2007-
strcpy(s, str_initcap(localized_abbrev_days[tm->tm_wday]));
2067+
strcpy(s, str_initcap(localized_abbrev_days[tm->tm_wday],
2068+
strlen(localized_abbrev_days[tm->tm_wday])));
20082069
else
20092070
strcpy(s, days_short[tm->tm_wday]);
20102071
s += strlen(s);
20112072
break;
20122073
case DCH_dy:
20132074
INVALID_FOR_INTERVAL;
20142075
if (S_TM(n->suffix))
2015-
strcpy(s, str_tolower(localized_abbrev_days[tm->tm_wday]));
2076+
strcpy(s, str_tolower(localized_abbrev_days[tm->tm_wday],
2077+
strlen(localized_abbrev_days[tm->tm_wday])));
20162078
else
20172079
{
20182080
strcpy(s, days_short[tm->tm_wday]);
@@ -4277,12 +4339,14 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
42774339
case NUM_rn:
42784340
if (IS_FILLMODE(Np->Num))
42794341
{
4280-
strcpy(Np->inout_p, str_tolower(Np->number_p));
4342+
strcpy(Np->inout_p, str_tolower(Np->number_p,
4343+
strlen(Np->number_p)));
42814344
Np->inout_p += strlen(Np->inout_p) - 1;
42824345
}
42834346
else
42844347
{
4285-
sprintf(Np->inout_p, "%15s", str_tolower(Np->number_p));
4348+
sprintf(Np->inout_p, "%15s", str_tolower(Np->number_p,
4349+
strlen(Np->number_p)));
42864350
Np->inout_p += strlen(Np->inout_p) - 1;
42874351
}
42884352
break;

0 commit comments

Comments
 (0)