i18n.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /* Copyright (C) 2004, 2006, 2008 Free Software Foundation, Inc.
  2. *
  3. * This library is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU Lesser General Public
  5. * License as published by the Free Software Foundation; either
  6. * version 2.1 of the License, or (at your option) any later version.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * Lesser General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Lesser General Public
  14. * License along with this library; if not, write to the Free Software
  15. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. # include <config.h>
  19. #endif
  20. #include "libguile/_scm.h"
  21. #include "libguile/feature.h"
  22. #include "libguile/i18n.h"
  23. #include "libguile/strings.h"
  24. #include "libguile/dynwind.h"
  25. #include "gettext.h"
  26. #include <locale.h>
  27. int
  28. scm_i_to_lc_category (SCM category, int allow_lc_all)
  29. {
  30. int c_category = scm_to_int (category);
  31. switch (c_category)
  32. {
  33. #ifdef LC_CTYPE
  34. case LC_CTYPE:
  35. #endif
  36. #ifdef LC_NUMERIC
  37. case LC_NUMERIC:
  38. #endif
  39. #ifdef LC_COLLATE
  40. case LC_COLLATE:
  41. #endif
  42. #ifdef LC_TIME
  43. case LC_TIME:
  44. #endif
  45. #ifdef LC_MONETARY
  46. case LC_MONETARY:
  47. #endif
  48. #ifdef LC_MESSAGES
  49. case LC_MESSAGES:
  50. #endif
  51. #ifdef LC_PAPER
  52. case LC_PAPER:
  53. #endif
  54. #ifdef LC_NAME
  55. case LC_NAME:
  56. #endif
  57. #ifdef LC_ADDRESS
  58. case LC_ADDRESS:
  59. #endif
  60. #ifdef LC_TELEPHONE
  61. case LC_TELEPHONE:
  62. #endif
  63. #ifdef LC_MEASUREMENT
  64. case LC_MEASUREMENT:
  65. #endif
  66. #ifdef LC_IDENTIFICATION
  67. case LC_IDENTIFICATION:
  68. #endif
  69. return c_category;
  70. #ifdef LC_ALL
  71. case LC_ALL:
  72. if (allow_lc_all)
  73. return c_category;
  74. #endif
  75. }
  76. scm_wrong_type_arg (0, 0, category);
  77. }
  78. SCM_DEFINE (scm_gettext, "gettext", 1, 2, 0,
  79. (SCM msgid, SCM domain, SCM category),
  80. "Return the translation of @var{msgid} in the message domain "
  81. "@var{domain}. @var{domain} is optional and defaults to the "
  82. "domain set through (textdomain). @var{category} is optional "
  83. "and defaults to LC_MESSAGES.")
  84. #define FUNC_NAME s_scm_gettext
  85. {
  86. char *c_msgid;
  87. char const *c_result;
  88. SCM result;
  89. scm_dynwind_begin (0);
  90. c_msgid = scm_to_locale_string (msgid);
  91. scm_dynwind_free (c_msgid);
  92. if (SCM_UNBNDP (domain))
  93. {
  94. /* 1 argument case. */
  95. c_result = gettext (c_msgid);
  96. }
  97. else
  98. {
  99. char *c_domain;
  100. c_domain = scm_to_locale_string (domain);
  101. scm_dynwind_free (c_domain);
  102. if (SCM_UNBNDP (category))
  103. {
  104. /* 2 argument case. */
  105. c_result = dgettext (c_domain, c_msgid);
  106. }
  107. else
  108. {
  109. /* 3 argument case. */
  110. int c_category;
  111. c_category = scm_i_to_lc_category (category, 0);
  112. c_result = dcgettext (c_domain, c_msgid, c_category);
  113. }
  114. }
  115. if (c_result == c_msgid)
  116. result = msgid;
  117. else
  118. result = scm_from_locale_string (c_result);
  119. scm_dynwind_end ();
  120. return result;
  121. }
  122. #undef FUNC_NAME
  123. SCM_DEFINE (scm_ngettext, "ngettext", 3, 2, 0,
  124. (SCM msgid, SCM msgid_plural, SCM n, SCM domain, SCM category),
  125. "Return the translation of @var{msgid}/@var{msgid_plural} in the "
  126. "message domain @var{domain}, with the plural form being chosen "
  127. "appropriately for the number @var{n}. @var{domain} is optional "
  128. "and defaults to the domain set through (textdomain). "
  129. "@var{category} is optional and defaults to LC_MESSAGES.")
  130. #define FUNC_NAME s_scm_ngettext
  131. {
  132. char *c_msgid;
  133. char *c_msgid_plural;
  134. unsigned long c_n;
  135. const char *c_result;
  136. SCM result;
  137. scm_dynwind_begin (0);
  138. c_msgid = scm_to_locale_string (msgid);
  139. scm_dynwind_free (c_msgid);
  140. c_msgid_plural = scm_to_locale_string (msgid_plural);
  141. scm_dynwind_free (c_msgid_plural);
  142. c_n = scm_to_ulong (n);
  143. if (SCM_UNBNDP (domain))
  144. {
  145. /* 3 argument case. */
  146. c_result = ngettext (c_msgid, c_msgid_plural, c_n);
  147. }
  148. else
  149. {
  150. char *c_domain;
  151. c_domain = scm_to_locale_string (domain);
  152. scm_dynwind_free (c_domain);
  153. if (SCM_UNBNDP (category))
  154. {
  155. /* 4 argument case. */
  156. c_result = dngettext (c_domain, c_msgid, c_msgid_plural, c_n);
  157. }
  158. else
  159. {
  160. /* 5 argument case. */
  161. int c_category;
  162. c_category = scm_i_to_lc_category (category, 0);
  163. c_result = dcngettext (c_domain, c_msgid, c_msgid_plural, c_n,
  164. c_category);
  165. }
  166. }
  167. if (c_result == c_msgid)
  168. result = msgid;
  169. else if (c_result == c_msgid_plural)
  170. result = msgid_plural;
  171. else
  172. result = scm_from_locale_string (c_result);
  173. scm_dynwind_end ();
  174. return result;
  175. }
  176. #undef FUNC_NAME
  177. SCM_DEFINE (scm_textdomain, "textdomain", 0, 1, 0,
  178. (SCM domainname),
  179. "If optional parameter @var{domainname} is supplied, "
  180. "set the textdomain. "
  181. "Return the textdomain.")
  182. #define FUNC_NAME s_scm_textdomain
  183. {
  184. char const *c_result;
  185. char *c_domain;
  186. SCM result = SCM_BOOL_F;
  187. scm_dynwind_begin (0);
  188. if (SCM_UNBNDP (domainname))
  189. c_domain = NULL;
  190. else
  191. {
  192. c_domain = scm_to_locale_string (domainname);
  193. scm_dynwind_free (c_domain);
  194. }
  195. c_result = textdomain (c_domain);
  196. if (c_result != NULL)
  197. result = scm_from_locale_string (c_result);
  198. else if (!SCM_UNBNDP (domainname))
  199. SCM_SYSERROR;
  200. scm_dynwind_end ();
  201. return result;
  202. }
  203. #undef FUNC_NAME
  204. SCM_DEFINE (scm_bindtextdomain, "bindtextdomain", 1, 1, 0,
  205. (SCM domainname, SCM directory),
  206. "If optional parameter @var{directory} is supplied, "
  207. "set message catalogs to directory @var{directory}. "
  208. "Return the directory bound to @var{domainname}.")
  209. #define FUNC_NAME s_scm_bindtextdomain
  210. {
  211. char *c_domain;
  212. char *c_directory;
  213. char const *c_result;
  214. SCM result;
  215. scm_dynwind_begin (0);
  216. if (SCM_UNBNDP (directory))
  217. c_directory = NULL;
  218. else
  219. {
  220. c_directory = scm_to_locale_string (directory);
  221. scm_dynwind_free (c_directory);
  222. }
  223. c_domain = scm_to_locale_string (domainname);
  224. scm_dynwind_free (c_domain);
  225. c_result = bindtextdomain (c_domain, c_directory);
  226. if (c_result != NULL)
  227. result = scm_from_locale_string (c_result);
  228. else if (!SCM_UNBNDP (directory))
  229. SCM_SYSERROR;
  230. else
  231. result = SCM_BOOL_F;
  232. scm_dynwind_end ();
  233. return result;
  234. }
  235. #undef FUNC_NAME
  236. SCM_DEFINE (scm_bind_textdomain_codeset, "bind-textdomain-codeset", 1, 1, 0,
  237. (SCM domainname, SCM encoding),
  238. "If optional parameter @var{encoding} is supplied, "
  239. "set encoding for message catalogs of @var{domainname}. "
  240. "Return the encoding of @var{domainname}.")
  241. #define FUNC_NAME s_scm_bind_textdomain_codeset
  242. {
  243. char *c_domain;
  244. char *c_encoding;
  245. char const *c_result;
  246. SCM result;
  247. scm_dynwind_begin (0);
  248. if (SCM_UNBNDP (encoding))
  249. c_encoding = NULL;
  250. else
  251. {
  252. c_encoding = scm_to_locale_string (encoding);
  253. scm_dynwind_free (c_encoding);
  254. }
  255. c_domain = scm_to_locale_string (domainname);
  256. scm_dynwind_free (c_domain);
  257. c_result = bind_textdomain_codeset (c_domain, c_encoding);
  258. if (c_result != NULL)
  259. result = scm_from_locale_string (c_result);
  260. else if (!SCM_UNBNDP (encoding))
  261. SCM_SYSERROR;
  262. else
  263. result = SCM_BOOL_F;
  264. scm_dynwind_end ();
  265. return result;
  266. }
  267. #undef FUNC_NAME
  268. void
  269. scm_init_i18n ()
  270. {
  271. scm_add_feature ("i18n");
  272. #include "libguile/i18n.x"
  273. }
  274. /*
  275. Local Variables:
  276. c-file-style: "gnu"
  277. End:
  278. */