1 /***********************************************************
2 Copyright (C) 1997 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.
9 ******************************************************************/
19 char *strdup
Py_PROTO((char *));
22 static char locale__doc__
[]="Support for POSIX locales.";
24 static PyObject
*Error
;
26 /* support functions for formatting floating point numbers */
28 static char setlocale__doc__
[]=
29 "(integer,string=None) -> string. Activates/queries locale processing."
32 /* to record the LC_NUMERIC settings */
33 static PyObject
* grouping
=0;
34 static PyObject
* thousands_sep
=0;
35 static PyObject
* decimal_point
=0;
36 /* if non-null, indicates that LC_NUMERIC is different from "C" */
37 static char* saved_numeric
=0;
39 /* the grouping is terminated by either 0 or CHAR_MAX */
45 PyObject
*result
,*val
=0;
47 /* empty string: no grouping at all */
49 for(i
=0;s
[i
]!='\0' && s
[i
]!=CHAR_MAX
;i
++)
51 result
= PyList_New(i
+1);
52 if(!result
)return NULL
;
56 val
=PyInt_FromLong(s
[i
]);
58 if(PyList_SetItem(result
,i
,val
)){
63 }while(s
[i
]!='\0' && s
[i
]!=CHAR_MAX
);
74 PyObject
*mods
,*strop
,*string
,*ulo
;
75 unsigned char ul
[256];
78 /* finding sys.modules */
79 mods
=PyImport_GetModuleDict();
81 /* finding the module */
82 string
=PyDict_GetItemString(mods
,"string");
84 string
=PyModule_GetDict(string
);
85 strop
=PyDict_GetItemString(mods
,"strop");
87 strop
=PyModule_GetDict(strop
);
88 if(!string
&& !strop
)return;
89 /* create uppercase */
91 for (c
= 0; c
< 256; c
++) {
95 ulo
=PyString_FromStringAndSize((const char *)ul
,n
);
98 PyDict_SetItemString(string
,"uppercase",ulo
);
100 PyDict_SetItemString(strop
,"uppercase",ulo
);
102 /* create lowercase */
104 for (c
= 0; c
< 256; c
++) {
108 ulo
=PyString_FromStringAndSize((const char *)ul
,n
);
111 PyDict_SetItemString(string
,"lowercase",ulo
);
113 PyDict_SetItemString(strop
,"lowercase",ulo
);
117 for (c
= 0; c
< 256; c
++) {
121 ulo
=PyString_FromStringAndSize((const char *)ul
,n
);
124 PyDict_SetItemString(string
,"letters",ulo
);
130 PyLocale_setlocale(self
,args
)
135 char *locale
=0,*result
;
136 PyObject
*result_object
;
138 if(!PyArg_ParseTuple(args
,"i|z",&category
,&locale
))return 0;
141 result
=setlocale(category
,locale
);
143 /* operation failed, no setting was changed */
144 PyErr_SetString(Error
,"locale setting not supported");
147 result_object
=PyString_FromString(result
);
148 if(!result
)return NULL
;
149 /* record changes to LC_NUMERIC */
150 if(category
==LC_NUMERIC
|| category
==LC_ALL
){
151 if(strcmp(locale
,"C")==0 || strcmp(locale
,"POSIX")==0){
152 /* user just asked for default numeric locale */
153 if(saved_numeric
)free(saved_numeric
);
156 /* remember values */
158 Py_XDECREF(grouping
);
159 grouping
=copy_grouping(lc
->grouping
);
160 Py_XDECREF(thousands_sep
);
161 thousands_sep
=PyString_FromString(lc
->thousands_sep
);
162 Py_XDECREF(decimal_point
);
163 decimal_point
=PyString_FromString(lc
->decimal_point
);
164 saved_numeric
= strdup(locale
);
167 setlocale(LC_NUMERIC
,"C");
170 /* record changes to LC_CTYPE */
171 if(category
==LC_CTYPE
|| category
==LC_ALL
)
173 /* things that got wrong up to here are ignored */
177 /* restore LC_NUMERIC first, if appropriate */
179 setlocale(LC_NUMERIC
,saved_numeric
);
180 result
=setlocale(category
,NULL
);
182 PyErr_SetString(Error
,"locale query failed");
185 result_object
=PyString_FromString(result
);
186 /* restore back to "C" */
188 setlocale(LC_NUMERIC
,"C");
190 return result_object
;
193 static char localeconv__doc__
[]=
194 "() -> dict. Returns numeric and monetary locale-specific parameters."
198 PyLocale_localeconv(self
,args
)
205 if(!PyArg_NoArgs(args
))return 0;
206 result
= PyDict_New();
208 /* if LC_NUMERIC is different in the C library, use saved value */
210 /* hopefully, the localeconv result survives the C library calls
212 #define RESULT_STRING(s) \
213 x=PyString_FromString(l->s);if(!x)goto failed;PyDict_SetItemString(result,#s,x);Py_XDECREF(x)
214 #define RESULT_INT(i) \
215 x=PyInt_FromLong(l->i);if(!x)goto failed;PyDict_SetItemString(result,#i,x);Py_XDECREF(x)
217 /* Numeric information */
219 /* cannot use localeconv results */
220 PyDict_SetItemString(result
,"decimal_point",decimal_point
);
221 PyDict_SetItemString(result
,"grouping",grouping
);
222 PyDict_SetItemString(result
,"thousands_sep",thousands_sep
);
224 RESULT_STRING(decimal_point
);
225 RESULT_STRING(thousands_sep
);
226 x
=copy_grouping(l
->grouping
);
228 PyDict_SetItemString(result
,"grouping",x
);
232 /* Monetary information */
233 RESULT_STRING(int_curr_symbol
);
234 RESULT_STRING(currency_symbol
);
235 RESULT_STRING(mon_decimal_point
);
236 RESULT_STRING(mon_thousands_sep
);
237 x
=copy_grouping(l
->mon_grouping
);
239 PyDict_SetItemString(result
,"mon_grouping",x
);
241 RESULT_STRING(positive_sign
);
242 RESULT_STRING(negative_sign
);
243 RESULT_INT(int_frac_digits
);
244 RESULT_INT(frac_digits
);
245 RESULT_INT(p_cs_precedes
);
246 RESULT_INT(p_sep_by_space
);
247 RESULT_INT(n_cs_precedes
);
248 RESULT_INT(n_sep_by_space
);
249 RESULT_INT(p_sign_posn
);
250 RESULT_INT(n_sign_posn
);
259 static char strcoll__doc__
[]=
260 "string,string -> int. Compares two strings according to the locale."
264 PyLocale_strcoll(self
,args
)
269 if(!PyArg_ParseTuple(args
,"ss",&s1
,&s2
))
271 return PyInt_FromLong(strcoll(s1
,s2
));
274 static char strxfrm__doc__
[]=
275 "string -> string. Returns a string that behaves for cmp locale-aware."
279 PyLocale_strxfrm(self
,args
)
286 if(!PyArg_ParseTuple(args
,"s",&s
))
288 /* assume no change in size, first */
292 n2
=strxfrm(buf
,s
,n1
);
294 /* more space needed */
295 buf
=Py_Realloc(buf
,n2
);
299 result
=PyString_FromString(buf
);
304 static struct PyMethodDef PyLocale_Methods
[] = {
305 {"setlocale",(PyCFunction
)PyLocale_setlocale
,1,setlocale__doc__
},
306 {"localeconv",(PyCFunction
)PyLocale_localeconv
,0,localeconv__doc__
},
307 {"strcoll",(PyCFunction
)PyLocale_strcoll
,1,strcoll__doc__
},
308 {"strxfrm",(PyCFunction
)PyLocale_strxfrm
,1,strxfrm__doc__
},
316 m
=Py_InitModule("_locale",PyLocale_Methods
);
317 d
= PyModule_GetDict(m
);
318 x
=PyInt_FromLong(LC_CTYPE
);
319 PyDict_SetItemString(d
,"LC_CTYPE",x
);
322 x
=PyInt_FromLong(LC_TIME
);
323 PyDict_SetItemString(d
,"LC_TIME",x
);
326 x
=PyInt_FromLong(LC_COLLATE
);
327 PyDict_SetItemString(d
,"LC_COLLATE",x
);
330 x
=PyInt_FromLong(LC_MONETARY
);
331 PyDict_SetItemString(d
,"LC_MONETARY",x
);
335 x
=PyInt_FromLong(LC_MESSAGES
);
336 PyDict_SetItemString(d
,"LC_MESSAGES",x
);
338 #endif /* LC_MESSAGES */
340 x
=PyInt_FromLong(LC_NUMERIC
);
341 PyDict_SetItemString(d
,"LC_NUMERIC",x
);
344 x
=PyInt_FromLong(LC_ALL
);
345 PyDict_SetItemString(d
,"LC_ALL",x
);
348 x
=PyInt_FromLong(CHAR_MAX
);
349 PyDict_SetItemString(d
,"CHAR_MAX",x
);
352 Error
= PyErr_NewException("locale.Error", NULL
, NULL
);
353 PyDict_SetItemString(d
, "Error", Error
);
355 x
=PyString_FromString(locale__doc__
);
356 PyDict_SetItemString(d
,"__doc__",x
);
360 Py_FatalError("Can't initialize module locale");