gettext.c 7.5 KB

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