PostgreSQL Source Code  git master
chklocale.c File Reference
#include "postgres.h"
#include <langinfo.h>
#include "mb/pg_wchar.h"
Include dependency graph for chklocale.c:

Go to the source code of this file.

Data Structures

struct  encoding_match
 

Functions

int pg_get_encoding_from_locale (const char *ctype, bool write_message)
 

Variables

static const struct encoding_match encoding_match_list []
 

Function Documentation

◆ pg_get_encoding_from_locale()

int pg_get_encoding_from_locale ( const char *  ctype,
bool  write_message 
)

Definition at line 305 of file chklocale.c.

306 {
307  char *sys;
308  int i;
309 
310 #ifndef WIN32
311  locale_t loc;
312 #endif
313 
314  /* Get the CODESET property, and also LC_CTYPE if not passed in */
315  if (!ctype)
316  ctype = setlocale(LC_CTYPE, NULL);
317 
318 
319  /* If locale is C or POSIX, we can allow all encodings */
320  if (pg_strcasecmp(ctype, "C") == 0 ||
321  pg_strcasecmp(ctype, "POSIX") == 0)
322  return PG_SQL_ASCII;
323 
324 
325 #ifndef WIN32
326  loc = newlocale(LC_CTYPE_MASK, ctype, (locale_t) 0);
327  if (loc == (locale_t) 0)
328  return -1; /* bogus ctype passed in? */
329 
330  sys = nl_langinfo_l(CODESET, loc);
331  if (sys)
332  sys = strdup(sys);
333 
334  freelocale(loc);
335 #else
336  sys = win32_get_codeset(ctype);
337 #endif
338 
339  if (!sys)
340  return -1; /* out of memory; unlikely */
341 
342  /* Check the table */
343  for (i = 0; encoding_match_list[i].system_enc_name; i++)
344  {
345  if (pg_strcasecmp(sys, encoding_match_list[i].system_enc_name) == 0)
346  {
347  free(sys);
349  }
350  }
351 
352  /* Special-case kluges for particular platforms go here */
353 
354 #ifdef __darwin__
355 
356  /*
357  * Current macOS has many locales that report an empty string for CODESET,
358  * but they all seem to actually use UTF-8.
359  */
360  if (strlen(sys) == 0)
361  {
362  free(sys);
363  return PG_UTF8;
364  }
365 #endif
366 
367  /*
368  * We print a warning if we got a CODESET string but couldn't recognize
369  * it. This means we need another entry in the table.
370  */
371  if (write_message)
372  {
373 #ifdef FRONTEND
374  fprintf(stderr, _("could not determine encoding for locale \"%s\": codeset is \"%s\""),
375  ctype, sys);
376  /* keep newline separate so there's only one translatable string */
377  fputc('\n', stderr);
378 #else
380  (errmsg("could not determine encoding for locale \"%s\": codeset is \"%s\"",
381  ctype, sys)));
382 #endif
383  }
384 
385  free(sys);
386  return -1;
387 }
static const struct encoding_match encoding_match_list[]
Definition: chklocale.c:49
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define _(x)
Definition: elog.c:90
#define WARNING
Definition: elog.h:36
#define ereport(elevel,...)
Definition: elog.h:149
#define free(a)
Definition: header.h:65
int i
Definition: isn.c:73
@ PG_SQL_ASCII
Definition: pg_wchar.h:226
@ PG_UTF8
Definition: pg_wchar.h:232
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define fprintf
Definition: port.h:242
enum pg_enc pg_enc_code
Definition: chklocale.c:45
const char * system_enc_name
Definition: chklocale.c:46
#define locale_t
Definition: win32_port.h:442
#define setlocale(a, b)
Definition: win32_port.h:485

Referenced by cache_locale_time(), check_encoding_locale_matches(), check_locale_encoding(), main(), PGLC_localeconv(), pqConnectOptions2(), PQsetClientEncoding(), and setup_locale_encoding().

Variable Documentation

◆ encoding_match_list

const struct encoding_match encoding_match_list[]
static

Definition at line 1 of file chklocale.c.