diff --git a/.gitattributes b/.gitattributes index a2ff65457379d4dd52db458574c9a53aa54bfe53..5208687425a7660c427ce323eb0fd3501b033d24 100644 --- a/.gitattributes +++ b/.gitattributes @@ -189,6 +189,10 @@ testfont binary /src/modules/Gdbm/configure.in foreign_ident /src/modules/Gdbm/gdbmmod.c foreign_ident /src/modules/Gdbm/testsuite.in foreign_ident +/src/modules/Gettext/Makefile.in foreign_ident +/src/modules/Gettext/acconfig.h foreign_ident +/src/modules/Gettext/configure.in foreign_ident +/src/modules/Gettext/gettext.c foreign_ident /src/modules/Gmp/Makefile.in foreign_ident /src/modules/Gmp/configure.in foreign_ident /src/modules/Gmp/gmp_machine.h.in foreign_ident diff --git a/src/modules/Gettext/.cvsignore b/src/modules/Gettext/.cvsignore new file mode 100644 index 0000000000000000000000000000000000000000..d45d29b97f067ce44f41aee72b02b7925026aac8 --- /dev/null +++ b/src/modules/Gettext/.cvsignore @@ -0,0 +1,15 @@ +.pure +Makefile +config.h +config.h.in +config.log +config.status +configure +dependencies +linker_options +make_variables +modlist_headers +modlist_segment +module_testsuite +stamp-h +stamp-h.in diff --git a/src/modules/Gettext/.gitignore b/src/modules/Gettext/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..14854305fb2b6104c4e95c6725c6d86599292015 --- /dev/null +++ b/src/modules/Gettext/.gitignore @@ -0,0 +1,15 @@ +/.pure +/Makefile +/config.h +/config.h.in +/config.log +/config.status +/configure +/dependencies +/linker_options +/make_variables +/modlist_headers +/modlist_segment +/module_testsuite +/stamp-h +/stamp-h.in diff --git a/src/modules/Gettext/Makefile.in b/src/modules/Gettext/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..24e33f30abcd6197ebab9b5eca529e50d71901c8 --- /dev/null +++ b/src/modules/Gettext/Makefile.in @@ -0,0 +1,10 @@ +# $Id: Makefile.in,v 1.1 2000/02/29 20:33:48 neotron Exp $ +@make_variables@ +VPATH=@srcdir@:@srcdir@/../..:../.. +OBJS=gettext.o +MODULE_LDFLAGS=@LDFLAGS@ @LIBS@ +NLSDIR=@NLSDIR@ +CONFIG_HEADERS=@CONFIG_HEADERS@ + +@dynamic_module_makefile@ +@dependencies@ diff --git a/src/modules/Gettext/acconfig.h b/src/modules/Gettext/acconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..e82040ef281d686cd0465422eabae81e9277af09 --- /dev/null +++ b/src/modules/Gettext/acconfig.h @@ -0,0 +1,14 @@ +/* + * $Id: acconfig.h,v 1.1 2000/02/29 20:33:48 neotron Exp $ + */ +#ifndef GETTEXT_CONFIG_H +#define GETTEXT_CONFIG_H + +@TOP@ + +/* define if you have gettext */ +#define HAVE_GETTEXT + +@BOTTOM@ + +#endif diff --git a/src/modules/Gettext/configure.in b/src/modules/Gettext/configure.in new file mode 100644 index 0000000000000000000000000000000000000000..cb35d80c58c9e24f789fd20d34f1147604385631 --- /dev/null +++ b/src/modules/Gettext/configure.in @@ -0,0 +1,32 @@ +# $Id: configure.in,v 1.1 2000/02/29 20:33:48 neotron Exp $ +AC_INIT(gettext.c) +AC_CONFIG_HEADER(config.h) + +AC_MODULE_INIT() + +AC_HAVE_HEADERS(locale.h libintl.h) + +######################################################################## +# gettext checking (localization) +######################################################################## + +AC_CHECK_FUNCS(setlocale) +AC_CHECK_FUNC(gettext, [AC_DEFINE(HAVE_GETTEXT)], + AC_CHECK_LIB(intl, gettext, [LIBS="$LIBS -lintl" + AC_DEFINE(HAVE_GETTEXT)], + INTLIBS="" )) + +AC_ARG_WITH(nlsdir, + [ --with-nlsdir=PATH specify where the locale stuff should go ]) + + +if test "x$NLSDIR" = "x"; then + if test "x$with_nlsdir" != "x"; then + NLSDIR=$with_nlsdir + else + NLSDIR='$(prefix)/share/locale' + fi +fi +AC_SUBST(NLSDIR) + +AC_OUTPUT(Makefile,echo FOO >stamp-h ) diff --git a/src/modules/Gettext/gettext.c b/src/modules/Gettext/gettext.c new file mode 100644 index 0000000000000000000000000000000000000000..71e7347c290728de77d79645002429c57edf4b34 --- /dev/null +++ b/src/modules/Gettext/gettext.c @@ -0,0 +1,451 @@ + +#include "global.h" +#include "config.h" + +#ifdef HAVE_GETTEXT + +#ifdef HAVE_LIBINTL_H +#include <libintl.h> +#endif +#ifdef HAVE_LOCALE_H +#include <locale.h> +#endif + +#include "stralloc.h" +#include "error.h" +#include "pike_macros.h" +#include "constants.h" +#include "interpret.h" +#include "svalue.h" +#include "mapping.h" +#include "module_support.h" + +RCSID("$Id: gettext.c,v 1.1 2000/02/29 20:33:48 neotron Exp $"); + +/* +**! module Locale.Gettext +**! +**! This module enables access to localization functions from within Pike. +**! +**! note +**! $Id: gettext.c,v 1.1 2000/02/29 20:33:48 neotron Exp $ +*/ + +/******************** PUBLIC FUNCTIONS BELOW THIS LINE */ + +/* +**! method string gettext(string msg) +**! +**! Return a translated version of msg within the context +**! of the current domain and locale. +**! +**! If there is not translation available, msg is returned. +**! arg string msg +**! The message to translate. +**! see also: bindtextdomain, textdomain, dgettext, dcgettext, setlocale, localeconv +*/ +void f_gettext(INT32 args) +{ + char *translated; + if (args != 1) + error( "Wrong number of arguments to Gettext.gettext()\n" ); + if (sp[-1].type != T_STRING) + error( "Bad argument 1 to Gettext.gettext(), expected string\n" ); + translated = gettext(sp[-1].u.string->str); + + pop_n_elems(args); + push_string(make_shared_string(translated)); +} + +/* +**! method string dgettext(string domain, string msg) +**! +**! Return a translated version of msg within the context +**! of the specified domain and current locale. +**! +**! If there is not translation available, msg is returned. +**! +**! arg string domain +**! The domain to lookup the message in. +**! arg string msg +**! The message to translate. +**! see also: bindtextdomain, textdomain, gettext, dcgettext, setlocale, localeconv +*/ +void f_dgettext(INT32 args) +{ + char *translated; + struct pike_string *domain, *msg; + get_all_args("Gettext.dgettext", args, "%S%S", &domain, &msg); + + translated = dgettext(domain->str, msg->str); + + pop_n_elems(args); + push_string(make_shared_string(translated)); +} + +/* +**! method string dcgettext(string domain, string msg, int category) +**! +**! Return a translated version of msg within the context of the +**! specified domain and current locale for the specified +**! category. Calling dcgettext with category +**! Locale.Gettext.LC_MESSAGES gives the same result as dgettext. +**! +**! If there is not translation available, msg is returned. +**! +**! arg string domain +**! The domain to lookup the message in. +**! arg string msg +**! The message to translate. +**! arg int category +**! The category which locale should be used. +**! see also: bindtextdomain, textdomain, gettext, dgettext, setlocale, localeconv +*/ +void f_dcgettext(INT32 args) +{ + char *translated; + struct pike_string *domain, *msg; + int category; + get_all_args("Gettext.dcgettext", args, "%S%S%d", &domain, &msg, &category); + + translated = dcgettext(domain->str, msg->str, category); + + pop_n_elems(args); + push_string(make_shared_string(translated)); +} +/* +**! method string textdomain(string domain|void) +**! method string textdomain(void) +**! +**! The textdomain() function sets or queries the name of the +**! current domain of the active LC_MESSAGES locale category. The +**! domainname argument is a string that can contain only the +**! characters allowed in legal filenames. +**! +**! The domainname argument is the unique name of a domain on the +**! system. If there are multiple versions of the same domain on +**! one system, namespace collisions can be avoided by using +**! bindtextdomain(). If textdomain() is not called, a default +**! domain is selected. The setting of domain made by the last +**! valid call to textdomain() remains valid across subsequent +**! calls to setlocale, and gettext(). +**! +**! The normal return value from textdomain() is a string +**! containing the current setting of the domain. If domainname is +**! void, textdomain() returns a string containing the current +**! domain. If textdomain() was not previously called and +**! domainname is void, the name of the default domain is +**! returned. +**� +**! arg string domainname +**! The name of the domain to be made the current domain. +**! see also: bindtextdomain, gettext, dgettext, dcgettext, setlocale, localeconv +*/ + +void f_textdomain(INT32 args) +{ + char *domain=NULL, *returnstring; + if (args != 0 && args != 1) + error( "Wrong number of arguments to Gettext.textdomain()\n" ); + + if(sp[-args].type == T_STRING) + domain = sp[-args].u.string->str; + else if(!(sp[-args].type == T_INT && sp[-args].u.integer == 0)) + error( "Bad argument 1 to Gettext.textdomain(), expected string|void\n" ); + returnstring = textdomain(domain); + pop_n_elems(args); + push_string(make_shared_string(returnstring)); +} + +/* +**! method string bindtextdomain(string|void domainname, string|void dirname) +**! +**! The bindtextdomain() function binds the path predicate for a +**! message domain domainname to the value contained in dirname. If +**! domainname is a non-empty string and has not been bound +**! previously, bindtextdomain() binds domainname with dirname. +**! +**! If domainname is a non-empty string and has been bound previously, +**! bindtextdomain() replaces the old binding with dirname. The dirname +**! argument can be an absolute or relative pathname being resolved when +**! gettext(), dgettext(), or dcgettext() are called. If domainname is +**! null pointer or an empty string, bindtextdomain() returns 0. User +**! defined domain names cannot begin with the string SYS_. Domain names +**! beginning with this string are reserved for system use. +**! +**! The return value from bindtextdomain() is a string containing +**! dirname or the directory binding associated with domainname if +**! dirname is void. If no binding is found, the default locale +**! path is returned. If domainname is void or an empty string, +**! bindtextdomain() takes no action and returns a 0. +**! +**! arg string domainname +**! The domain to query or bind a path to. +**! arg string dirname +**! The directory name to bind to the choosen domain. +**! see also: textdomain, gettext, dgettext, dcgettext, setlocale, localeconv +*/ + +void f_bindtextdomain(INT32 args) +{ + char *returnstring, *domain = NULL, *dirname = NULL; + if (args < 1 || args > 2) + error( "Wrong number of arguments to Gettext.bindtextdomain()\n" ); + switch(args) + { + case 2: + if(sp[-1].type == T_STRING) + dirname = sp[-1].u.string->str; + else if(!(sp[-1].type == T_INT && sp[-1].u.integer == 0)) + error( "Bad argument 2 to Gettext.bindtextdomain(), expected string|void\n" ); + /* FALLTHROUGH */ + + case 1: + if(sp[-args].type == T_STRING) + domain = sp[-args].u.string->str; + else if(!(sp[-args].type == T_INT && sp[-args].u.integer == 0)) + error( "Bad argument 1 to Gettext.bindtextdomain(), expected string|void\n" ); + } + returnstring = bindtextdomain(domain, dirname); + pop_n_elems(args); + if(returnstring == NULL) + push_int(0); + else + push_string(make_shared_string(returnstring)); +} + +/* +**! method int setlocale(int category, string locale) +**! +**! The setlocale() function is used to set the program's +**! current locale. If locale is "C" or "POSIX", the current +**! locale is set to the portable locale. +**! +**! If locale is "", the locale is set to the default locale which +**! is selected from the environment variable LANG. +**! +**! The argument category determines which functions are +**! influenced by the new locale: +**! +**! <b>Locale.Gettext.LC_ALL</b> for all of the locale. +**! +**! <b>Locale.Gettext.LC_COLLATE</b> for the functions strcoll() and +**! strxfrm() (used by pike, but not directly accessible). +**! +**! <b>Locale.Gettext.LC_CTYPE</b> for the character classification and +**! conversion routines. +**! +**! <b>Locale.Gettext.LC_MONETARY</b> for localeconv(). +**! +**! <b>Locale.Gettext.LC_NUMERIC</b> for the decimal character. +**! +**! <b>Locale.Gettext.LC_TIME</b> for strftime() (currently not accessible +**! from Pike). +**! +**! arg int category +**! The category in which to set the locale. +**! arg string locale +**! The locale to change to +**! returns 1 if the locale setting successed, 0 for failure +**! see also: bindtextdomain, textdomain, gettext, dgettext, dcgettext, localeconv +*/ + +void f_setlocale(INT32 args) +{ + char *returnstring; + struct pike_string *locale; + int category; + get_all_args("Gettext.setlocale", args, "%d%S", &category, &locale); + + fprintf(stderr, "locale: %s, category: %d\n", locale->str, category); + returnstring = setlocale(category, locale->str); + pop_n_elems(args); + if(returnstring == NULL) + push_int(0); + else + push_int(1); +} + +#define MAPSTR(key, value) do {\ + struct svalue val; struct pike_string *valstr; \ + val.type = T_STRING; \ + valstr = make_shared_string(locale->value);\ + val.u.string = valstr; \ + mapping_string_insert(map, make_shared_string(key), &val);\ + free_string(valstr); \ + } while(0) +#define MAPINT(key, value) do {\ + struct svalue val; struct pike_string *valstr; \ + val.type = T_INT; \ + val.u.integer = (int)locale->value; \ + mapping_string_insert(map, make_shared_string(key), &val);\ + } while(0) + +**! method mapping localeconv() +**! The localeconv() function returns a mapping with settings for +**! the current locale. This mapping contains all values +**! associated with the locale categories LC_NUMERIC and +**! LC_MONETARY. +**! +**! <b>string decimal_point:</b> +**! The decimal-point character used to format +**! non-monetary quantities. +**! +**! <b>string thousands_sep:</b> +**! The character used to separate groups of digits to +**! the left of the decimal-point character in +**! formatted non-monetary quantities. +**! +**! <b>string int_curr_symbol:</b> +**! The international currency symbol applicable to +**! the current locale, left-justified within a +**! four-character space-padded field. The character +**! sequences should match with those specified in ISO +**! 4217 Codes for the Representation of Currency and +**! Funds. +**! +**! <b>string currency_symbol:</b> +**! The local currency symbol applicable to the +**! current locale. +**! +**! <b>string mon_decimal_point:</b> +**! The decimal point used to format monetary quantities. +**! +**! <b>string mon_thousands_sep:</b> +**! The separator for groups of digits to the left of +**! the decimal point in formatted monetary quantities. +**! +**! <b>string positive_sign:</b> +**! The string used to indicate a non-negative-valued +**! formatted monetary quantity. +**! +**! <b>string negative_sign:</b> +**! The string used to indicate a negative-valued +**! formatted monetary quantity. +**! +**! <b>int int_frac_digits:</b> +**! The number of fractional digits (those to the +**! right of the decimal point) to be displayed in an +**! internationally formatted monetary quantity. +**! +**! <b>int frac_digits:</b> +**! The number of fractional digits (those to the +**! right of the decimal point) to be displayed in a +**! formatted monetary quantity. +**! +**! <b>int p_cs_precedes:</b> +**! Set to 1 or 0 if the currency_symbol respectively +**! precedes or succeeds the value for a non-negative +**! formatted monetary quantity. +**! +**! <b>int p_sep_by_space:</b> +**! Set to 1 or 0 if the currency_symbol respectively +**! is or is not separated by a space from the value +**! for a non-negative formatted monetary quantity. +**! +**! <b>int n_cs_precedes:</b> +**! Set to 1 or 0 if the currency_symbol respectively +**! precedes or succeeds the value for a negative +**! formatted monetary quantity. +**! +**! <b>int n_sep_by_space:</b> +**! Set to 1 or 0 if the currency_symbol respectively +**! is or is not separated by a space from the value +**! for a negative formatted monetary quantity. +**! +**! <b>int p_sign_posn:</b> +**! Set to a value indicating the positioning of the +**! positive_sign for a non-negative formatted +**! monetary quantity. The value of p_sign_posn is +**! interpreted according to the following: +**! +**! 0 - Parentheses surround the quantity and +**! currency_symbol. +**! +**! 1 - The sign string precedes the quantity and +**! currency_symbol. +**! +**! 2 - The sign string succeeds the quantity +**! and currency_symbol. +**! +**! 3 - The sign string immediately precedes the +**! currency_symbol. +**! +**! 4 - The sign string immediately succeeds the +**! currency_symbol. +**! +**! <b>int n_sign_posn:</b> +**! Set to a value indicating the positioning of the +**! negative_sign for a negative formatted monetary +**! quantity. The value of n_sign_posn is interpreted +**! according to the rules described under p_sign_posn. +void f_localeconv(INT32 args) +{ + struct lconv *locale; /* Information about the current locale */ + struct mapping *map; + map = allocate_mapping(18); + locale = localeconv(); + + MAPSTR("decimal_point", decimal_point); + MAPSTR("thousands_sep", thousands_sep); + MAPSTR("int_curr_symbol", int_curr_symbol); + MAPSTR("currency_symbol", currency_symbol); + MAPSTR("mon_decimal_point", mon_decimal_point); + MAPSTR("mon_thousands_sep", mon_thousands_sep); + MAPSTR("positive_sign", positive_sign); + MAPSTR("negative_sign", negative_sign); + + /* + MAPCHAR("grouping", grouping); + MAPCHAR("mon_grouping", mon_grouping); + */ + + MAPINT("int_frac_digits", int_frac_digits); + MAPINT("frac_digits", frac_digits); + MAPINT("p_cs_precedes", p_cs_precedes); + MAPINT("p_sep_by_space", p_sep_by_space); + MAPINT("n_cs_precedes", n_cs_precedes); + MAPINT("n_sep_by_space", n_sep_by_space); + MAPINT("p_sign_posn", p_sign_posn); + MAPINT("n_sign_posn", n_sign_posn); + push_mapping(map); +} + +void pike_module_init(void) +{ + +/* function(void:string) */ + + ADD_FUNCTION("gettext", f_gettext, tFunc(tStr,tStr), + OPT_EXTERNAL_DEPEND); + ADD_FUNCTION("setlocale", f_setlocale, tFunc(tInt tStr,tInt), + OPT_EXTERNAL_DEPEND); + ADD_FUNCTION("dgettext", f_dgettext, tFunc(tStr tStr,tStr), + OPT_EXTERNAL_DEPEND); + ADD_FUNCTION("dcgettext", f_dcgettext, tFunc(tStr tStr tInt,tStr), + OPT_EXTERNAL_DEPEND); + ADD_FUNCTION("bindtextdomain", f_bindtextdomain, tFunc(tOr(tStr,tVoid) tOr(tStr,tVoid), tOr(tStr,tVoid)), + OPT_EXTERNAL_DEPEND); + ADD_FUNCTION("textdomain", f_textdomain, tFunc(tOr(tStr, tVoid),tStr), + OPT_EXTERNAL_DEPEND); + ADD_FUNCTION("localeconv", f_localeconv, tFunc(tVoid, tMapping), OPT_EXTERNAL_DEPEND); + + add_integer_constant("LC_ALL", LC_ALL, 0); + add_integer_constant("LC_COLLATE", LC_COLLATE, 0); + add_integer_constant("LC_CTYPE", LC_CTYPE, 0); + add_integer_constant("LC_MESSAGES", LC_MESSAGES, 0); + add_integer_constant("LC_MONETARY", LC_MONETARY, 0); + add_integer_constant("LC_NUMERIC", LC_NUMERIC, 0); + add_integer_constant("LC_TIME", LC_TIME, 0); +} + +void pike_module_exit(void) +{ + +} +#else + +void pike_module_init(void) {} +void pike_module_exit(void) {} + +#endif