Commit 5afaa2e4 authored by Tom Lane's avatar Tom Lane

Rationalize code placement between wchar.c, encnames.c, and mbutils.c.

Move all the backend-only code that'd crept into wchar.c and encnames.c
into mbutils.c.

To remove the last few #ifdef dependencies from wchar.c and encnames.c,
also make the following changes:

* Adjust get_encoding_name_for_icu to return NULL, not throw an error,
for unsupported encodings.  Its sole caller can perfectly well throw an
error instead.  (While at it, I also made this function and its sibling
is_encoding_supported_by_icu proof against out-of-range encoding IDs.)

* Remove the overlength-name error condition from pg_char_to_encoding.
It's completely silly not to treat that just like any other
the-name-is-not-in-the-table case.

Also, get rid of pg_mic_mblen --- there's no obvious reason why
conv.c shouldn't call pg_mule_mblen instead.

Other than that, this is just code movement and comment-polishing with
no functional changes.  Notably, I reordered declarations in pg_wchar.h
to show which functions are frontend-accessible and which are not.

Discussion: https://postgr.es/m/CA+TgmoYO8oq-iy8E02rD8eX25T-9SmyxKWqqks5OMHxKvGXpXQ@mail.gmail.com
parent 3d4cb5d6
......@@ -1555,9 +1555,14 @@ init_icu_converter(void)
UConverter *conv;
if (icu_converter)
return;
return; /* already done */
icu_encoding_name = get_encoding_name_for_icu(GetDatabaseEncoding());
if (!icu_encoding_name)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("encoding \"%s\" not supported by ICU",
pg_encoding_to_char(GetDatabaseEncoding()))));
status = U_ZERO_ERROR;
conv = ucnv_open(icu_encoding_name, &status);
......
......@@ -115,7 +115,7 @@ mic2latin(const unsigned char *mic, unsigned char *p, int len,
}
else
{
int l = pg_mic_mblen(mic);
int l = pg_mule_mblen(mic);
if (len < l)
report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic,
......@@ -217,7 +217,7 @@ mic2latin_with_table(const unsigned char *mic,
}
else
{
int l = pg_mic_mblen(mic);
int l = pg_mule_mblen(mic);
if (len < l)
report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic,
......
This diff is collapsed.
......@@ -10,12 +10,7 @@
*
*-------------------------------------------------------------------------
*/
#ifdef FRONTEND
#include "postgres_fe.h"
#else
#include "postgres.h"
#include "utils/builtins.h"
#endif
#include "c.h"
#include <ctype.h>
#include <unistd.h>
......@@ -310,6 +305,7 @@ static const pg_encname pg_encname_tbl[] =
#else
#define DEF_ENC2NAME(name, codepage) { #name, PG_##name, codepage }
#endif
const pg_enc2name pg_enc2name_tbl[] =
{
DEF_ENC2NAME(SQL_ASCII, 0),
......@@ -409,10 +405,8 @@ const pg_enc2gettext pg_enc2gettext_tbl[] =
};
#ifndef FRONTEND
/*
* Table of encoding names for ICU
* Table of encoding names for ICU (currently covers backend encodings only)
*
* Reference: <https://ssl.icu-project.org/icu-bin/convexp>
*
......@@ -457,33 +451,32 @@ static const char *const pg_enc2icu_tbl[] =
"KOI8-U", /* PG_KOI8U */
};
/*
* Is this encoding supported by ICU?
*/
bool
is_encoding_supported_by_icu(int encoding)
{
if (!PG_VALID_BE_ENCODING(encoding))
return false;
return (pg_enc2icu_tbl[encoding] != NULL);
}
/*
* Returns ICU's name for encoding, or NULL if not supported
*/
const char *
get_encoding_name_for_icu(int encoding)
{
const char *icu_encoding_name;
StaticAssertStmt(lengthof(pg_enc2icu_tbl) == PG_ENCODING_BE_LAST + 1,
"pg_enc2icu_tbl incomplete");
icu_encoding_name = pg_enc2icu_tbl[encoding];
if (!icu_encoding_name)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("encoding \"%s\" not supported by ICU",
pg_encoding_to_char(encoding))));
return icu_encoding_name;
if (!PG_VALID_BE_ENCODING(encoding))
return NULL;
return pg_enc2icu_tbl[encoding];
}
#endif /* not FRONTEND */
/* ----------
* Encoding checks, for error returns -1 else encoding id
......@@ -523,9 +516,10 @@ pg_valid_server_encoding_id(int encoding)
return PG_VALID_BE_ENCODING(encoding);
}
/* ----------
* Remove irrelevant chars from encoding name
* ----------
/*
* Remove irrelevant chars from encoding name, store at *newkey
*
* (Caller's responsibility to provide a large enough buffer)
*/
static char *
clean_encoding_name(const char *key, char *newkey)
......@@ -547,11 +541,10 @@ clean_encoding_name(const char *key, char *newkey)
return newkey;
}
/* ----------
/*
* Search encoding by encoding name
*
* Returns encoding ID, or -1 for error
* ----------
* Returns encoding ID, or -1 if not recognized
*/
int
pg_char_to_encoding(const char *name)
......@@ -568,16 +561,8 @@ pg_char_to_encoding(const char *name)
return -1;
if (strlen(name) >= NAMEDATALEN)
{
#ifdef FRONTEND
fprintf(stderr, "encoding name too long\n");
return -1;
#else
ereport(ERROR,
(errcode(ERRCODE_NAME_TOO_LONG),
errmsg("encoding name too long")));
#endif
}
return -1; /* it's certainly not in the table */
key = clean_encoding_name(name, buff);
while (last >= base)
......@@ -599,16 +584,6 @@ pg_char_to_encoding(const char *name)
return -1;
}
#ifndef FRONTEND
Datum
PG_char_to_encoding(PG_FUNCTION_ARGS)
{
Name s = PG_GETARG_NAME(0);
PG_RETURN_INT32(pg_char_to_encoding(NameStr(*s)));
}
#endif
const char *
pg_encoding_to_char(int encoding)
{
......@@ -621,15 +596,3 @@ pg_encoding_to_char(int encoding)
}
return "";
}
#ifndef FRONTEND
Datum
PG_encoding_to_char(PG_FUNCTION_ARGS)
{
int32 encoding = PG_GETARG_INT32(0);
const char *encoding_name = pg_encoding_to_char(encoding);
return DirectFunctionCall1(namein, CStringGetDatum(encoding_name));
}
#endif
This diff is collapsed.
......@@ -9,7 +9,7 @@
* src/include/mb/pg_wchar.h
*
* NOTES
* This is used both by the backend and by libpq, but should not be
* This is used both by the backend and by frontends, but should not be
* included by libpq client programs. In particular, a libpq client
* should not assume that the encoding IDs used by the version of libpq
* it's linked to match up with the IDs declared here.
......@@ -345,12 +345,6 @@ typedef struct pg_enc2gettext
extern const pg_enc2gettext pg_enc2gettext_tbl[];
/*
* Encoding names for ICU
*/
extern bool is_encoding_supported_by_icu(int encoding);
extern const char *get_encoding_name_for_icu(int encoding);
/*
* pg_wchar stuff
*/
......@@ -539,8 +533,27 @@ extern const char *pg_encoding_to_char(int encoding);
extern int pg_valid_server_encoding_id(int encoding);
/*
* Remaining functions are not considered part of libpq's API, though many
* of them do exist inside libpq.
* These functions are available to frontend code that links with libpgcommon
* (in addition to the ones just above). The constant tables declared
* earlier in this file are also available from libpgcommon.
*/
extern int pg_encoding_mblen(int encoding, const char *mbstr);
extern int pg_encoding_dsplen(int encoding, const char *mbstr);
extern int pg_encoding_verifymb(int encoding, const char *mbstr, int len);
extern int pg_encoding_max_length(int encoding);
extern int pg_valid_client_encoding(const char *name);
extern int pg_valid_server_encoding(const char *name);
extern bool is_encoding_supported_by_icu(int encoding);
extern const char *get_encoding_name_for_icu(int encoding);
extern unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string);
extern pg_wchar utf8_to_unicode(const unsigned char *c);
extern bool pg_utf8_islegal(const unsigned char *source, int length);
extern int pg_utf_mblen(const unsigned char *s);
extern int pg_mule_mblen(const unsigned char *s);
/*
* The remaining functions are backend-only.
*/
extern int pg_mb2wchar(const char *from, pg_wchar *to);
extern int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len);
......@@ -556,18 +569,12 @@ extern int pg_char_and_wchar_strncmp(const char *s1, const pg_wchar *s2, size_t
extern size_t pg_wchar_strlen(const pg_wchar *wstr);
extern int pg_mblen(const char *mbstr);
extern int pg_dsplen(const char *mbstr);
extern int pg_encoding_mblen(int encoding, const char *mbstr);
extern int pg_encoding_dsplen(int encoding, const char *mbstr);
extern int pg_encoding_verifymb(int encoding, const char *mbstr, int len);
extern int pg_mule_mblen(const unsigned char *mbstr);
extern int pg_mic_mblen(const unsigned char *mbstr);
extern int pg_mbstrlen(const char *mbstr);
extern int pg_mbstrlen_with_len(const char *mbstr, int len);
extern int pg_mbcliplen(const char *mbstr, int len, int limit);
extern int pg_encoding_mbcliplen(int encoding, const char *mbstr,
int len, int limit);
extern int pg_mbcharcliplen(const char *mbstr, int len, int limit);
extern int pg_encoding_max_length(int encoding);
extern int pg_database_encoding_max_length(void);
extern mbcharacter_incrementer pg_database_encoding_character_incrementer(void);
......@@ -587,12 +594,6 @@ extern int GetMessageEncoding(void);
extern int pg_bind_textdomain_codeset(const char *domainname);
#endif
extern int pg_valid_client_encoding(const char *name);
extern int pg_valid_server_encoding(const char *name);
extern unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string);
extern pg_wchar utf8_to_unicode(const unsigned char *c);
extern int pg_utf_mblen(const unsigned char *);
extern unsigned char *pg_do_encoding_conversion(unsigned char *src, int len,
int src_encoding,
int dest_encoding);
......@@ -647,8 +648,6 @@ extern void mic2latin_with_table(const unsigned char *mic, unsigned char *p,
int len, int lc, int encoding,
const unsigned char *tab);
extern bool pg_utf8_islegal(const unsigned char *source, int length);
#ifdef WIN32
extern WCHAR *pgwin32_message_to_UTF16(const char *str, int len, int *utf16len);
#endif
......
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