#include "config.h"
#include "bashtypes.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashintl.h"
#include "bashansi.h"
#include <stdio.h>
#include "chartypes.h"
#include "shell.h"
#include "input.h"
extern int dump_translatable_strings, dump_po_strings;
static char *default_locale;
static char *default_domain;
static char *default_dir;
static char *lc_all;
static char *lang;
static int reset_locale_vars __P((void));
static void locale_setblanks __P((void));
void
set_default_locale ()
{
#if defined (HAVE_SETLOCALE)
default_locale = setlocale (LC_ALL, "");
if (default_locale)
default_locale = savestring (default_locale);
#endif
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
}
void
set_default_locale_vars ()
{
char *val;
#if defined (HAVE_SETLOCALE)
# if defined (LC_CTYPE)
val = get_string_value ("LC_CTYPE");
if (val == 0 && lc_all && *lc_all)
{
setlocale (LC_CTYPE, lc_all);
locale_setblanks ();
}
# endif
# if defined (LC_COLLATE)
val = get_string_value ("LC_COLLATE");
if (val == 0 && lc_all && *lc_all)
setlocale (LC_COLLATE, lc_all);
# endif
# if defined (LC_MESSAGES)
val = get_string_value ("LC_MESSAGES");
if (val == 0 && lc_all && *lc_all)
setlocale (LC_MESSAGES, lc_all);
# endif
# if defined (LC_NUMERIC)
val = get_string_value ("LC_NUMERIC");
if (val == 0 && lc_all && *lc_all)
setlocale (LC_NUMERIC, lc_all);
# endif
# if defined (LC_TIME)
val = get_string_value ("LC_TIME");
if (val == 0 && lc_all && *lc_all)
setlocale (LC_TIME, lc_all);
# endif
#endif
val = get_string_value ("TEXTDOMAIN");
if (val && *val)
{
FREE (default_domain);
default_domain = savestring (val);
#if 0
textdomain (default_domain);
#endif
}
val = get_string_value ("TEXTDOMAINDIR");
if (val && *val)
{
FREE (default_dir);
default_dir = savestring (val);
if (default_domain && *default_domain)
bindtextdomain (default_domain, default_dir);
}
}
int
set_locale_var (var, value)
char *var, *value;
{
int r;
if (var[0] == 'T' && var[10] == 0)
{
FREE (default_domain);
default_domain = value ? savestring (value) : (char *)NULL;
#if 0
textdomain (default_domain);
#endif
return (1);
}
else if (var[0] == 'T')
{
FREE (default_dir);
default_dir = value ? savestring (value) : (char *)NULL;
if (default_domain && *default_domain)
bindtextdomain (default_domain, default_dir);
return (1);
}
else if (var[3] == 'A')
{
FREE (lc_all);
if (value)
lc_all = savestring (value);
else
{
lc_all = (char *)xmalloc (1);
lc_all[0] = '\0';
}
#if defined (HAVE_SETLOCALE)
r = *lc_all ? (setlocale (LC_ALL, lc_all) != 0) : reset_locale_vars ();
locale_setblanks ();
return r;
#else
return (1);
#endif
}
#if defined (HAVE_SETLOCALE)
else if (var[3] == 'C' && var[4] == 'T')
{
# if defined (LC_CTYPE)
if (lc_all == 0 || *lc_all == '\0')
{
r = (setlocale (LC_CTYPE, get_locale_var ("LC_CTYPE")) != 0);
locale_setblanks ();
return r;
}
# endif
}
else if (var[3] == 'C' && var[4] == 'O')
{
# if defined (LC_COLLATE)
if (lc_all == 0 || *lc_all == '\0')
return (setlocale (LC_COLLATE, get_locale_var ("LC_COLLATE")) != 0);
# endif
}
else if (var[3] == 'M' && var[4] == 'E')
{
# if defined (LC_MESSAGES)
if (lc_all == 0 || *lc_all == '\0')
return (setlocale (LC_MESSAGES, get_locale_var ("LC_MESSAGES")) != 0);
# endif
}
else if (var[3] == 'N' && var[4] == 'U')
{
# if defined (LC_NUMERIC)
if (lc_all == 0 || *lc_all == '\0')
return (setlocale (LC_NUMERIC, get_locale_var ("LC_NUMERIC")) != 0);
# endif
}
else if (var[3] == 'T' && var[4] == 'I')
{
# if defined (LC_TIME)
if (lc_all == 0 || *lc_all == '\0')
return (setlocale (LC_TIME, get_locale_var ("LC_TIME")) != 0);
# endif
}
#endif
return (0);
}
int
set_lang (var, value)
char *var, *value;
{
FREE (lang);
if (value)
lang = savestring (value);
else
{
lang = (char *)xmalloc (1);
lang[0] = '\0';
}
return ((lc_all == 0 || *lc_all == 0) ? reset_locale_vars () : 0);
}
void
set_default_lang ()
{
char *v;
v = get_string_value ("LC_ALL");
set_locale_var ("LC_ALL", v);
v = get_string_value ("LANG");
set_lang ("LANG", v);
}
char *
get_locale_var (var)
char *var;
{
char *locale;
locale = lc_all;
if (locale == 0 || *locale == 0)
locale = get_string_value (var);
if (locale == 0 || *locale == 0)
locale = lang;
if (locale == 0 || *locale == 0)
locale = default_locale;
return (locale);
}
static int
reset_locale_vars ()
{
#if defined (HAVE_SETLOCALE)
if (lang == 0 || *lang == '\0')
maybe_make_export_env ();
if (setlocale (LC_ALL, lang ? lang : "") == 0)
return 0;
# if defined (LC_CTYPE)
setlocale (LC_CTYPE, get_locale_var ("LC_CTYPE"));
# endif
# if defined (LC_COLLATE)
setlocale (LC_COLLATE, get_locale_var ("LC_COLLATE"));
# endif
# if defined (LC_MESSAGES)
setlocale (LC_MESSAGES, get_locale_var ("LC_MESSAGES"));
# endif
# if defined (LC_NUMERIC)
setlocale (LC_NUMERIC, get_locale_var ("LC_NUMERIC"));
# endif
# if defined (LC_TIME)
setlocale (LC_TIME, get_locale_var ("LC_TIME"));
# endif
locale_setblanks ();
#endif
return 1;
}
char *
localetrans (string, len, lenp)
char *string;
int len, *lenp;
{
char *locale, *t;
char *translated;
int tlen;
if (string == 0 || *string == 0)
{
if (lenp)
*lenp = 0;
return ((char *)NULL);
}
locale = get_locale_var ("LC_MESSAGES");
if (locale == 0 || locale[0] == '\0' ||
(locale[0] == 'C' && locale[1] == '\0') || STREQ (locale, "POSIX"))
{
t = (char *)xmalloc (len + 1);
strcpy (t, string);
if (lenp)
*lenp = len;
return (t);
}
if (default_domain && *default_domain)
translated = dgettext (default_domain, string);
else
translated = string;
if (translated == string)
{
t = (char *)xmalloc (len + 1);
strcpy (t, string);
if (lenp)
*lenp = len;
}
else
{
tlen = strlen (translated);
t = (char *)xmalloc (tlen + 1);
strcpy (t, translated);
if (lenp)
*lenp = tlen;
}
return (t);
}
char *
mk_msgstr (string, foundnlp)
char *string;
int *foundnlp;
{
register int c, len;
char *result, *r, *s;
for (len = 0, s = string; s && *s; s++)
{
len++;
if (*s == '"' || *s == '\\')
len++;
else if (*s == '\n')
len += 5;
}
r = result = (char *)xmalloc (len + 3);
*r++ = '"';
for (s = string; s && (c = *s); s++)
{
if (c == '\n')
{
*r++ = '\\';
*r++ = 'n';
*r++ = '"';
*r++ = '\n';
*r++ = '"';
if (foundnlp)
*foundnlp = 1;
continue;
}
if (c == '"' || c == '\\')
*r++ = '\\';
*r++ = c;
}
*r++ = '"';
*r++ = '\0';
return result;
}
char *
localeexpand (string, start, end, lineno, lenp)
char *string;
int start, end, lineno, *lenp;
{
int len, tlen, foundnl;
char *temp, *t, *t2;
temp = (char *)xmalloc (end - start + 1);
for (tlen = 0, len = start; len < end; )
temp[tlen++] = string[len++];
temp[tlen] = '\0';
if (dump_translatable_strings)
{
if (dump_po_strings)
{
foundnl = 0;
t = mk_msgstr (temp, &foundnl);
t2 = foundnl ? "\"\"\n" : "";
printf ("#: %s:%d\nmsgid %s%s\nmsgstr \"\"\n",
yy_input_name (), lineno, t2, t);
free (t);
}
else
printf ("\"%s\"\n", temp);
if (lenp)
*lenp = tlen;
return (temp);
}
else if (*temp)
{
t = localetrans (temp, tlen, &len);
free (temp);
if (lenp)
*lenp = len;
return (t);
}
else
{
if (lenp)
*lenp = 0;
return (temp);
}
}
static void
locale_setblanks ()
{
int x;
for (x = 0; x < sh_syntabsiz; x++)
{
if (isblank (x))
sh_syntaxtab[x] |= CSHBRK|CBLANK;
else if (member (x, shell_break_chars))
{
sh_syntaxtab[x] |= CSHBRK;
sh_syntaxtab[x] &= ~CBLANK;
}
else
sh_syntaxtab[x] &= ~(CSHBRK|CBLANK);
}
}