Manual py3k backport: [svn r74158] Issue #6218: Make io.BytesIO and io.StringIO pickl...
[python.git] / Modules / _localemodule.c
blob94d0014bbc09b30b89910b74173821f42b92879b
1 /***********************************************************
2 Copyright (C) 1997, 2002, 2003 Martin von Loewis
4 Permission to use, copy, modify, and distribute this software and its
5 documentation for any purpose and without fee is hereby granted,
6 provided that the above copyright notice appear in all copies.
8 This software comes with no warranty. Use at your own risk.
10 ******************************************************************/
12 #include "Python.h"
14 #include <stdio.h>
15 #include <locale.h>
16 #include <string.h>
17 #include <ctype.h>
19 #ifdef HAVE_ERRNO_H
20 #include <errno.h>
21 #endif
23 #ifdef HAVE_LANGINFO_H
24 #include <langinfo.h>
25 #endif
27 #ifdef HAVE_LIBINTL_H
28 #include <libintl.h>
29 #endif
31 #ifdef HAVE_WCHAR_H
32 #include <wchar.h>
33 #endif
35 #if defined(MS_WINDOWS)
36 #define WIN32_LEAN_AND_MEAN
37 #include <windows.h>
38 #endif
40 #ifdef RISCOS
41 char *strdup(const char *);
42 #endif
44 PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
46 static PyObject *Error;
48 /* support functions for formatting floating point numbers */
50 PyDoc_STRVAR(setlocale__doc__,
51 "(integer,string=None) -> string. Activates/queries locale processing.");
53 /* the grouping is terminated by either 0 or CHAR_MAX */
54 static PyObject*
55 copy_grouping(char* s)
57 int i;
58 PyObject *result, *val = NULL;
60 if (s[0] == '\0')
61 /* empty string: no grouping at all */
62 return PyList_New(0);
64 for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++)
65 ; /* nothing */
67 result = PyList_New(i+1);
68 if (!result)
69 return NULL;
71 i = -1;
72 do {
73 i++;
74 val = PyInt_FromLong(s[i]);
75 if (!val)
76 break;
77 if (PyList_SetItem(result, i, val)) {
78 Py_DECREF(val);
79 val = NULL;
80 break;
82 } while (s[i] != '\0' && s[i] != CHAR_MAX);
84 if (!val) {
85 Py_DECREF(result);
86 return NULL;
89 return result;
92 static void
93 fixup_ulcase(void)
95 PyObject *mods, *strop, *string, *ulo;
96 unsigned char ul[256];
97 int n, c;
99 /* find the string and strop modules */
100 mods = PyImport_GetModuleDict();
101 if (!mods)
102 return;
103 string = PyDict_GetItemString(mods, "string");
104 if (string)
105 string = PyModule_GetDict(string);
106 strop=PyDict_GetItemString(mods, "strop");
107 if (strop)
108 strop = PyModule_GetDict(strop);
109 if (!string && !strop)
110 return;
112 /* create uppercase map string */
113 n = 0;
114 for (c = 0; c < 256; c++) {
115 if (isupper(c))
116 ul[n++] = c;
118 ulo = PyString_FromStringAndSize((const char *)ul, n);
119 if (!ulo)
120 return;
121 if (string)
122 PyDict_SetItemString(string, "uppercase", ulo);
123 if (strop)
124 PyDict_SetItemString(strop, "uppercase", ulo);
125 Py_DECREF(ulo);
127 /* create lowercase string */
128 n = 0;
129 for (c = 0; c < 256; c++) {
130 if (islower(c))
131 ul[n++] = c;
133 ulo = PyString_FromStringAndSize((const char *)ul, n);
134 if (!ulo)
135 return;
136 if (string)
137 PyDict_SetItemString(string, "lowercase", ulo);
138 if (strop)
139 PyDict_SetItemString(strop, "lowercase", ulo);
140 Py_DECREF(ulo);
142 /* create letters string */
143 n = 0;
144 for (c = 0; c < 256; c++) {
145 if (isalpha(c))
146 ul[n++] = c;
148 ulo = PyString_FromStringAndSize((const char *)ul, n);
149 if (!ulo)
150 return;
151 if (string)
152 PyDict_SetItemString(string, "letters", ulo);
153 Py_DECREF(ulo);
156 static PyObject*
157 PyLocale_setlocale(PyObject* self, PyObject* args)
159 int category;
160 char *locale = NULL, *result;
161 PyObject *result_object;
163 if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale))
164 return NULL;
166 if (locale) {
167 /* set locale */
168 result = setlocale(category, locale);
169 if (!result) {
170 /* operation failed, no setting was changed */
171 PyErr_SetString(Error, "unsupported locale setting");
172 return NULL;
174 result_object = PyString_FromString(result);
175 if (!result_object)
176 return NULL;
177 /* record changes to LC_CTYPE */
178 if (category == LC_CTYPE || category == LC_ALL)
179 fixup_ulcase();
180 /* things that got wrong up to here are ignored */
181 PyErr_Clear();
182 } else {
183 /* get locale */
184 result = setlocale(category, NULL);
185 if (!result) {
186 PyErr_SetString(Error, "locale query failed");
187 return NULL;
189 result_object = PyString_FromString(result);
191 return result_object;
194 PyDoc_STRVAR(localeconv__doc__,
195 "() -> dict. Returns numeric and monetary locale-specific parameters.");
197 static PyObject*
198 PyLocale_localeconv(PyObject* self)
200 PyObject* result;
201 struct lconv *l;
202 PyObject *x;
204 result = PyDict_New();
205 if (!result)
206 return NULL;
208 /* if LC_NUMERIC is different in the C library, use saved value */
209 l = localeconv();
211 /* hopefully, the localeconv result survives the C library calls
212 involved herein */
214 #define RESULT_STRING(s)\
215 x = PyString_FromString(l->s);\
216 if (!x) goto failed;\
217 PyDict_SetItemString(result, #s, x);\
218 Py_XDECREF(x)
220 #define RESULT_INT(i)\
221 x = PyInt_FromLong(l->i);\
222 if (!x) goto failed;\
223 PyDict_SetItemString(result, #i, x);\
224 Py_XDECREF(x)
226 /* Numeric information */
227 RESULT_STRING(decimal_point);
228 RESULT_STRING(thousands_sep);
229 x = copy_grouping(l->grouping);
230 if (!x)
231 goto failed;
232 PyDict_SetItemString(result, "grouping", x);
233 Py_XDECREF(x);
235 /* Monetary information */
236 RESULT_STRING(int_curr_symbol);
237 RESULT_STRING(currency_symbol);
238 RESULT_STRING(mon_decimal_point);
239 RESULT_STRING(mon_thousands_sep);
240 x = copy_grouping(l->mon_grouping);
241 if (!x)
242 goto failed;
243 PyDict_SetItemString(result, "mon_grouping", x);
244 Py_XDECREF(x);
245 RESULT_STRING(positive_sign);
246 RESULT_STRING(negative_sign);
247 RESULT_INT(int_frac_digits);
248 RESULT_INT(frac_digits);
249 RESULT_INT(p_cs_precedes);
250 RESULT_INT(p_sep_by_space);
251 RESULT_INT(n_cs_precedes);
252 RESULT_INT(n_sep_by_space);
253 RESULT_INT(p_sign_posn);
254 RESULT_INT(n_sign_posn);
255 return result;
257 failed:
258 Py_XDECREF(result);
259 Py_XDECREF(x);
260 return NULL;
263 PyDoc_STRVAR(strcoll__doc__,
264 "string,string -> int. Compares two strings according to the locale.");
266 static PyObject*
267 PyLocale_strcoll(PyObject* self, PyObject* args)
269 #if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE)
270 char *s1,*s2;
272 if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2))
273 return NULL;
274 return PyInt_FromLong(strcoll(s1, s2));
275 #else
276 PyObject *os1, *os2, *result = NULL;
277 wchar_t *ws1 = NULL, *ws2 = NULL;
278 int rel1 = 0, rel2 = 0, len1, len2;
280 if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2))
281 return NULL;
282 /* If both arguments are byte strings, use strcoll. */
283 if (PyString_Check(os1) && PyString_Check(os2))
284 return PyInt_FromLong(strcoll(PyString_AS_STRING(os1),
285 PyString_AS_STRING(os2)));
286 /* If neither argument is unicode, it's an error. */
287 if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) {
288 PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings");
290 /* Convert the non-unicode argument to unicode. */
291 if (!PyUnicode_Check(os1)) {
292 os1 = PyUnicode_FromObject(os1);
293 if (!os1)
294 return NULL;
295 rel1 = 1;
297 if (!PyUnicode_Check(os2)) {
298 os2 = PyUnicode_FromObject(os2);
299 if (!os2) {
300 if (rel1) {
301 Py_DECREF(os1);
303 return NULL;
305 rel2 = 1;
307 /* Convert the unicode strings to wchar[]. */
308 len1 = PyUnicode_GET_SIZE(os1) + 1;
309 ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t));
310 if (!ws1) {
311 PyErr_NoMemory();
312 goto done;
314 if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1)
315 goto done;
316 ws1[len1 - 1] = 0;
317 len2 = PyUnicode_GET_SIZE(os2) + 1;
318 ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t));
319 if (!ws2) {
320 PyErr_NoMemory();
321 goto done;
323 if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1)
324 goto done;
325 ws2[len2 - 1] = 0;
326 /* Collate the strings. */
327 result = PyInt_FromLong(wcscoll(ws1, ws2));
328 done:
329 /* Deallocate everything. */
330 if (ws1) PyMem_FREE(ws1);
331 if (ws2) PyMem_FREE(ws2);
332 if (rel1) {
333 Py_DECREF(os1);
335 if (rel2) {
336 Py_DECREF(os2);
338 return result;
339 #endif
343 PyDoc_STRVAR(strxfrm__doc__,
344 "string -> string. Returns a string that behaves for cmp locale-aware.");
346 static PyObject*
347 PyLocale_strxfrm(PyObject* self, PyObject* args)
349 char *s, *buf;
350 size_t n1, n2;
351 PyObject *result;
353 if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
354 return NULL;
356 /* assume no change in size, first */
357 n1 = strlen(s) + 1;
358 buf = PyMem_Malloc(n1);
359 if (!buf)
360 return PyErr_NoMemory();
361 n2 = strxfrm(buf, s, n1) + 1;
362 if (n2 > n1) {
363 /* more space needed */
364 buf = PyMem_Realloc(buf, n2);
365 if (!buf)
366 return PyErr_NoMemory();
367 strxfrm(buf, s, n2);
369 result = PyString_FromString(buf);
370 PyMem_Free(buf);
371 return result;
374 #if defined(MS_WINDOWS)
375 static PyObject*
376 PyLocale_getdefaultlocale(PyObject* self)
378 char encoding[100];
379 char locale[100];
381 PyOS_snprintf(encoding, sizeof(encoding), "cp%d", GetACP());
383 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
384 LOCALE_SISO639LANGNAME,
385 locale, sizeof(locale))) {
386 Py_ssize_t i = strlen(locale);
387 locale[i++] = '_';
388 if (GetLocaleInfo(LOCALE_USER_DEFAULT,
389 LOCALE_SISO3166CTRYNAME,
390 locale+i, (int)(sizeof(locale)-i)))
391 return Py_BuildValue("ss", locale, encoding);
394 /* If we end up here, this windows version didn't know about
395 ISO639/ISO3166 names (it's probably Windows 95). Return the
396 Windows language identifier instead (a hexadecimal number) */
398 locale[0] = '0';
399 locale[1] = 'x';
400 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
401 locale+2, sizeof(locale)-2)) {
402 return Py_BuildValue("ss", locale, encoding);
405 /* cannot determine the language code (very unlikely) */
406 Py_INCREF(Py_None);
407 return Py_BuildValue("Os", Py_None, encoding);
409 #endif
411 #ifdef HAVE_LANGINFO_H
412 #define LANGINFO(X) {#X, X}
413 static struct langinfo_constant{
414 char* name;
415 int value;
416 } langinfo_constants[] =
418 /* These constants should exist on any langinfo implementation */
419 LANGINFO(DAY_1),
420 LANGINFO(DAY_2),
421 LANGINFO(DAY_3),
422 LANGINFO(DAY_4),
423 LANGINFO(DAY_5),
424 LANGINFO(DAY_6),
425 LANGINFO(DAY_7),
427 LANGINFO(ABDAY_1),
428 LANGINFO(ABDAY_2),
429 LANGINFO(ABDAY_3),
430 LANGINFO(ABDAY_4),
431 LANGINFO(ABDAY_5),
432 LANGINFO(ABDAY_6),
433 LANGINFO(ABDAY_7),
435 LANGINFO(MON_1),
436 LANGINFO(MON_2),
437 LANGINFO(MON_3),
438 LANGINFO(MON_4),
439 LANGINFO(MON_5),
440 LANGINFO(MON_6),
441 LANGINFO(MON_7),
442 LANGINFO(MON_8),
443 LANGINFO(MON_9),
444 LANGINFO(MON_10),
445 LANGINFO(MON_11),
446 LANGINFO(MON_12),
448 LANGINFO(ABMON_1),
449 LANGINFO(ABMON_2),
450 LANGINFO(ABMON_3),
451 LANGINFO(ABMON_4),
452 LANGINFO(ABMON_5),
453 LANGINFO(ABMON_6),
454 LANGINFO(ABMON_7),
455 LANGINFO(ABMON_8),
456 LANGINFO(ABMON_9),
457 LANGINFO(ABMON_10),
458 LANGINFO(ABMON_11),
459 LANGINFO(ABMON_12),
461 #ifdef RADIXCHAR
462 /* The following are not available with glibc 2.0 */
463 LANGINFO(RADIXCHAR),
464 LANGINFO(THOUSEP),
465 /* YESSTR and NOSTR are deprecated in glibc, since they are
466 a special case of message translation, which should be rather
467 done using gettext. So we don't expose it to Python in the
468 first place.
469 LANGINFO(YESSTR),
470 LANGINFO(NOSTR),
472 LANGINFO(CRNCYSTR),
473 #endif
475 LANGINFO(D_T_FMT),
476 LANGINFO(D_FMT),
477 LANGINFO(T_FMT),
478 LANGINFO(AM_STR),
479 LANGINFO(PM_STR),
481 /* The following constants are available only with XPG4, but...
482 AIX 3.2. only has CODESET.
483 OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have
484 a few of the others.
485 Solution: ifdef-test them all. */
486 #ifdef CODESET
487 LANGINFO(CODESET),
488 #endif
489 #ifdef T_FMT_AMPM
490 LANGINFO(T_FMT_AMPM),
491 #endif
492 #ifdef ERA
493 LANGINFO(ERA),
494 #endif
495 #ifdef ERA_D_FMT
496 LANGINFO(ERA_D_FMT),
497 #endif
498 #ifdef ERA_D_T_FMT
499 LANGINFO(ERA_D_T_FMT),
500 #endif
501 #ifdef ERA_T_FMT
502 LANGINFO(ERA_T_FMT),
503 #endif
504 #ifdef ALT_DIGITS
505 LANGINFO(ALT_DIGITS),
506 #endif
507 #ifdef YESEXPR
508 LANGINFO(YESEXPR),
509 #endif
510 #ifdef NOEXPR
511 LANGINFO(NOEXPR),
512 #endif
513 #ifdef _DATE_FMT
514 /* This is not available in all glibc versions that have CODESET. */
515 LANGINFO(_DATE_FMT),
516 #endif
517 {0, 0}
520 PyDoc_STRVAR(nl_langinfo__doc__,
521 "nl_langinfo(key) -> string\n"
522 "Return the value for the locale information associated with key.");
524 static PyObject*
525 PyLocale_nl_langinfo(PyObject* self, PyObject* args)
527 int item, i;
528 if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item))
529 return NULL;
530 /* Check whether this is a supported constant. GNU libc sometimes
531 returns numeric values in the char* return value, which would
532 crash PyString_FromString. */
533 for (i = 0; langinfo_constants[i].name; i++)
534 if (langinfo_constants[i].value == item) {
535 /* Check NULL as a workaround for GNU libc's returning NULL
536 instead of an empty string for nl_langinfo(ERA). */
537 const char *result = nl_langinfo(item);
538 return PyString_FromString(result != NULL ? result : "");
540 PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant");
541 return NULL;
543 #endif /* HAVE_LANGINFO_H */
545 #ifdef HAVE_LIBINTL_H
547 PyDoc_STRVAR(gettext__doc__,
548 "gettext(msg) -> string\n"
549 "Return translation of msg.");
551 static PyObject*
552 PyIntl_gettext(PyObject* self, PyObject *args)
554 char *in;
555 if (!PyArg_ParseTuple(args, "s", &in))
556 return 0;
557 return PyString_FromString(gettext(in));
560 PyDoc_STRVAR(dgettext__doc__,
561 "dgettext(domain, msg) -> string\n"
562 "Return translation of msg in domain.");
564 static PyObject*
565 PyIntl_dgettext(PyObject* self, PyObject *args)
567 char *domain, *in;
568 if (!PyArg_ParseTuple(args, "zs", &domain, &in))
569 return 0;
570 return PyString_FromString(dgettext(domain, in));
573 PyDoc_STRVAR(dcgettext__doc__,
574 "dcgettext(domain, msg, category) -> string\n"
575 "Return translation of msg in domain and category.");
577 static PyObject*
578 PyIntl_dcgettext(PyObject *self, PyObject *args)
580 char *domain, *msgid;
581 int category;
582 if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category))
583 return 0;
584 return PyString_FromString(dcgettext(domain,msgid,category));
587 PyDoc_STRVAR(textdomain__doc__,
588 "textdomain(domain) -> string\n"
589 "Set the C library's textdmain to domain, returning the new domain.");
591 static PyObject*
592 PyIntl_textdomain(PyObject* self, PyObject* args)
594 char *domain;
595 if (!PyArg_ParseTuple(args, "z", &domain))
596 return 0;
597 domain = textdomain(domain);
598 if (!domain) {
599 PyErr_SetFromErrno(PyExc_OSError);
600 return NULL;
602 return PyString_FromString(domain);
605 PyDoc_STRVAR(bindtextdomain__doc__,
606 "bindtextdomain(domain, dir) -> string\n"
607 "Bind the C library's domain to dir.");
609 static PyObject*
610 PyIntl_bindtextdomain(PyObject* self,PyObject*args)
612 char *domain, *dirname;
613 if (!PyArg_ParseTuple(args, "sz", &domain, &dirname))
614 return 0;
615 if (!strlen(domain)) {
616 PyErr_SetString(Error, "domain must be a non-empty string");
617 return 0;
619 dirname = bindtextdomain(domain, dirname);
620 if (!dirname) {
621 PyErr_SetFromErrno(PyExc_OSError);
622 return NULL;
624 return PyString_FromString(dirname);
627 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
628 PyDoc_STRVAR(bind_textdomain_codeset__doc__,
629 "bind_textdomain_codeset(domain, codeset) -> string\n"
630 "Bind the C library's domain to codeset.");
632 static PyObject*
633 PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args)
635 char *domain,*codeset;
636 if (!PyArg_ParseTuple(args, "sz", &domain, &codeset))
637 return NULL;
638 codeset = bind_textdomain_codeset(domain, codeset);
639 if (codeset)
640 return PyString_FromString(codeset);
641 Py_RETURN_NONE;
643 #endif
645 #endif
647 static struct PyMethodDef PyLocale_Methods[] = {
648 {"setlocale", (PyCFunction) PyLocale_setlocale,
649 METH_VARARGS, setlocale__doc__},
650 {"localeconv", (PyCFunction) PyLocale_localeconv,
651 METH_NOARGS, localeconv__doc__},
652 {"strcoll", (PyCFunction) PyLocale_strcoll,
653 METH_VARARGS, strcoll__doc__},
654 {"strxfrm", (PyCFunction) PyLocale_strxfrm,
655 METH_VARARGS, strxfrm__doc__},
656 #if defined(MS_WINDOWS)
657 {"_getdefaultlocale", (PyCFunction) PyLocale_getdefaultlocale, METH_NOARGS},
658 #endif
659 #ifdef HAVE_LANGINFO_H
660 {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo,
661 METH_VARARGS, nl_langinfo__doc__},
662 #endif
663 #ifdef HAVE_LIBINTL_H
664 {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS,
665 gettext__doc__},
666 {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS,
667 dgettext__doc__},
668 {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS,
669 dcgettext__doc__},
670 {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS,
671 textdomain__doc__},
672 {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS,
673 bindtextdomain__doc__},
674 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
675 {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset,
676 METH_VARARGS, bind_textdomain_codeset__doc__},
677 #endif
678 #endif
679 {NULL, NULL}
682 PyMODINIT_FUNC
683 init_locale(void)
685 PyObject *m, *d, *x;
686 #ifdef HAVE_LANGINFO_H
687 int i;
688 #endif
690 m = Py_InitModule("_locale", PyLocale_Methods);
691 if (m == NULL)
692 return;
694 d = PyModule_GetDict(m);
696 x = PyInt_FromLong(LC_CTYPE);
697 PyDict_SetItemString(d, "LC_CTYPE", x);
698 Py_XDECREF(x);
700 x = PyInt_FromLong(LC_TIME);
701 PyDict_SetItemString(d, "LC_TIME", x);
702 Py_XDECREF(x);
704 x = PyInt_FromLong(LC_COLLATE);
705 PyDict_SetItemString(d, "LC_COLLATE", x);
706 Py_XDECREF(x);
708 x = PyInt_FromLong(LC_MONETARY);
709 PyDict_SetItemString(d, "LC_MONETARY", x);
710 Py_XDECREF(x);
712 #ifdef LC_MESSAGES
713 x = PyInt_FromLong(LC_MESSAGES);
714 PyDict_SetItemString(d, "LC_MESSAGES", x);
715 Py_XDECREF(x);
716 #endif /* LC_MESSAGES */
718 x = PyInt_FromLong(LC_NUMERIC);
719 PyDict_SetItemString(d, "LC_NUMERIC", x);
720 Py_XDECREF(x);
722 x = PyInt_FromLong(LC_ALL);
723 PyDict_SetItemString(d, "LC_ALL", x);
724 Py_XDECREF(x);
726 x = PyInt_FromLong(CHAR_MAX);
727 PyDict_SetItemString(d, "CHAR_MAX", x);
728 Py_XDECREF(x);
730 Error = PyErr_NewException("locale.Error", NULL, NULL);
731 PyDict_SetItemString(d, "Error", Error);
733 x = PyString_FromString(locale__doc__);
734 PyDict_SetItemString(d, "__doc__", x);
735 Py_XDECREF(x);
737 #ifdef HAVE_LANGINFO_H
738 for (i = 0; langinfo_constants[i].name; i++) {
739 PyModule_AddIntConstant(m, langinfo_constants[i].name,
740 langinfo_constants[i].value);
742 #endif
746 Local variables:
747 c-basic-offset: 4
748 indent-tabs-mode: nil
749 End: