Allow the user to set the default character encoding.
/COMPRESSION=@{ON,OFF@}
/SCOMPRESSION=@{ON,OFF@}
-(security)
+(miscellaneous)
/SAFER=ON
+ /LOCALE='string'
+
(obsolete settings accepted for compatibility, but ignored)
/BOXSTRING=@{'xxx','xxxxxxxxxxx'@}
overwrite files, for instance) but it is an improvement.
When set, this setting cannot be reset during the same session, for
obvious security reasons.
+
+@item LOCALE
+@cindex locale
+@cindex encoding, characters
+This item is used to set the default character encoding.
+The encoding may be specified either as an encoding name or alias
+(see @url{http://www.iana.org/assignments/character-sets}), or
+as a locale name.
+If given as a locale name, only the character encoding of the
+locale is relevant.
+
+System files written by PSPP will use this encoding.
+System files read by PSPP, for which the encoding is unknown, will be
+interpreted using this encoding.
+
+The full list of valid encodings and locale names/alias are operating system
+dependent.
+The following are all examples of acceptable syntax on common GNU/Linux
+systems.
+@example
+
+SET LOCALE='iso-8859-1'.
+
+SET LOCALE='ru_RU.cp1251'.
+
+SET LOCALE='japanese'.
+
+@end example
+
+Contrary to the intuition, this command does not affect any aspect
+of the system's locale.
@end table
@node SHOW
#include "xalloc.h"
#include <libpspp/integer-format.h>
#include <libpspp/message.h>
+#include <libpspp/i18n.h>
#include "error.h"
#include <libpspp/float-format.h>
#include <libpspp/integer-format.h>
#include <libpspp/message.h>
+#include <libpspp/i18n.h>
#include <math/random.h>
#include <output/journal.h>
#include <output/output.h>
journal=custom;
log=custom;
length=custom;
+ locale=custom;
listing=custom;
lowres=lores:auto/on/off;
lpi=integer "x>0" "%s must be greater than 0";
return 1;
}
+static int
+stc_custom_locale (struct lexer *lexer, struct dataset *ds UNUSED,
+ struct cmd_set *cmd UNUSED, void *aux UNUSED)
+{
+ const struct string *s;
+
+ lex_match (lexer, '=');
+
+ if ( !lex_force_string (lexer))
+ return 0;
+
+ s = lex_tokstr (lexer);
+
+ lex_get (lexer);
+
+ /* First try this string as an encoding name */
+ if ( valid_encoding (ds_cstr (s)))
+ set_default_encoding (ds_cstr (s));
+
+ /* Now try as a locale name (or alias) */
+ else if (set_encoding_from_locale (ds_cstr (s)))
+ {
+ }
+ else
+ {
+ msg (ME, _("%s is not a recognised encoding or locale name"),
+ ds_cstr (s));
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
static int
stc_custom_seed (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void *aux UNUSED)
{
msg (SN, _("LENGTH is %d."), settings_get_viewlength ());
}
+static void
+show_locale (const struct dataset *ds UNUSED)
+{
+ msg (SN, _("LOCALE is %s"), get_default_encoding ());
+}
+
static void
show_mxerrs (const struct dataset *ds UNUSED)
{
{"ERRORS", show_errors},
{"FORMAT", show_format},
{"LENGTH", show_length},
+ {"LOCALE", show_locale},
{"MXERRS", show_mxerrs},
{"MXLOOPS", show_mxloops},
{"MXWARNS", show_mxwarns},
}
+const char *
+get_default_encoding (void)
+{
+ return default_encoding;
+}
+
+void
+set_default_encoding (const char *enc)
+{
+ free (default_encoding);
+ default_encoding = strdup (enc);
+}
+
+
+/* Attempts to set the encoding from a locale name
+ returns true if successfull.
+ This function does not (should not!) alter the current locale.
+*/
+bool
+set_encoding_from_locale (const char *loc)
+{
+ bool ok = true;
+ char *c_encoding;
+ char *loc_encoding;
+ char *tmp = strdup (setlocale (LC_CTYPE, NULL));
+
+ setlocale (LC_CTYPE, "C");
+ c_encoding = strdup (locale_charset ());
+
+ setlocale (LC_CTYPE, loc);
+ loc_encoding = strdup (locale_charset ());
+
+
+ if ( 0 == strcmp (loc_encoding, c_encoding))
+ {
+ ok = false;
+ }
+
+
+ setlocale (LC_CTYPE, tmp);
+
+ free (tmp);
+
+ if (ok)
+ {
+ free (default_encoding);
+ default_encoding = loc_encoding;
+ }
+ else
+ free (loc_encoding);
+
+ free (c_encoding);
+
+ return ok;
+}
+
void
i18n_done (void)
{
+bool
+valid_encoding (const char *enc)
+{
+ iconv_t conv = iconv_open ("UTF8", enc);
+
+ if ( conv == (iconv_t) -1)
+ return false;
+
+ iconv_close (conv);
+
+ return true;
+}
+
/* Return the system local's idea of the
decimal seperator character */
#ifndef I18N_H
#define I18N_H
+#include <stdbool.h>
+
void i18n_done (void);
void i18n_init (void);
-
#define UTF8 "UTF-8"
char * recode_string (const char *to, const char *from,
const char *text, int len);
+bool valid_encoding (const char *enc);
+
/* Return the decimal separator according to the
system locale */
char get_system_decimal (void);
+const char * get_default_encoding (void);
+void set_default_encoding (const char *enc);
+
+bool set_encoding_from_locale (const char *loc);
+
+
#endif /* i18n.h */