Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 220ecc8

Browse files
committed
Martin von Loewis' _locale module (locale.py follows tomorrow).
1 parent 3931df9 commit 220ecc8

1 file changed

Lines changed: 355 additions & 0 deletions

File tree

Modules/_localemodule.c

Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
/***********************************************************
2+
Copyright (C) 1997 Martin von Löwis
3+
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.
7+
8+
This software comes with no warranty. Use at your own risk.
9+
******************************************************************/
10+
11+
#include <stdio.h>
12+
#include <errno.h>
13+
#include <locale.h>
14+
#include <string.h>
15+
#include <limits.h>
16+
#include "Python.h"
17+
18+
static char locale__doc__[]="Support for POSIX locales.";
19+
20+
static PyObject *Error;
21+
22+
/* support functions for formatting floating point numbers */
23+
24+
static char setlocale__doc__[]=
25+
"(integer,string=None) -> string. Activates/queries locale processing."
26+
;
27+
28+
/* to record the LC_NUMERIC settings */
29+
static PyObject* grouping=0;
30+
static PyObject* thousands_sep=0;
31+
static PyObject* decimal_point=0;
32+
/* if non-null, indicates that LC_NUMERIC is different from "C" */
33+
static char* saved_numeric=0;
34+
35+
/* the grouping is terminated by either 0 or CHAR_MAX */
36+
static PyObject*
37+
copy_grouping(s)
38+
char* s;
39+
{
40+
int i;
41+
PyObject *result,*val=0;
42+
if(s[0]=='\0')
43+
/* empty string: no grouping at all */
44+
return PyList_New(0);
45+
for(i=0;s[i]!='\0' && s[i]!=CHAR_MAX;i++)
46+
/* nothing */;
47+
result = PyList_New(i+1);
48+
if(!result)return NULL;
49+
i=-1;
50+
do{
51+
i++;
52+
val=PyInt_FromLong(s[i]);
53+
if(!val)break;
54+
if(PyList_SetItem(result,i,val)){
55+
Py_DECREF(val);
56+
val=0;
57+
break;
58+
}
59+
}while(s[i]!='\0' && s[i]!=CHAR_MAX);
60+
if(!val){
61+
Py_DECREF(result);
62+
return NULL;
63+
}
64+
return result;
65+
}
66+
67+
static void
68+
fixup_ulcase()
69+
{
70+
PyObject *mods,*strop,*string,*ulo;
71+
unsigned char ul[256];
72+
int n,c;
73+
74+
/* finding sys.modules */
75+
mods=PyImport_GetModuleDict();
76+
if(!mods)return;
77+
/* finding the module */
78+
string=PyDict_GetItemString(mods,"string");
79+
if(string)
80+
string=PyModule_GetDict(string);
81+
strop=PyDict_GetItemString(mods,"strop");
82+
if(strop)
83+
strop=PyModule_GetDict(strop);
84+
if(!string && !strop)return;
85+
/* create uppercase */
86+
n = 0;
87+
for (c = 0; c < 256; c++) {
88+
if (isupper(c))
89+
ul[n++] = c;
90+
}
91+
ulo=PyString_FromStringAndSize(ul,n);
92+
if(!ulo)return;
93+
if(string)
94+
PyDict_SetItemString(string,"uppercase",ulo);
95+
if(strop)
96+
PyDict_SetItemString(strop,"uppercase",ulo);
97+
Py_DECREF(ulo);
98+
/* create lowercase */
99+
n = 0;
100+
for (c = 0; c < 256; c++) {
101+
if (islower(c))
102+
ul[n++] = c;
103+
}
104+
ulo=PyString_FromStringAndSize(ul,n);
105+
if(!ulo)return;
106+
if(string)
107+
PyDict_SetItemString(string,"lowercase",ulo);
108+
if(strop)
109+
PyDict_SetItemString(strop,"lowercase",ulo);
110+
Py_DECREF(ulo);
111+
/* create letters */
112+
n = 0;
113+
for (c = 0; c < 256; c++) {
114+
if (isalpha(c))
115+
ul[n++] = c;
116+
}
117+
ulo=PyString_FromStringAndSize(ul,n);
118+
if(!ulo)return;
119+
if(string)
120+
PyDict_SetItemString(string,"letters",ulo);
121+
Py_DECREF(ulo);
122+
}
123+
124+
125+
static PyObject*
126+
PyLocale_setlocale(self,args)
127+
PyObject *self;
128+
PyObject *args;
129+
{
130+
int category;
131+
char *locale=0,*result;
132+
PyObject *result_object;
133+
struct lconv *lc;
134+
if(!PyArg_ParseTuple(args,"i|z",&category,&locale))return 0;
135+
if(locale){
136+
/* set locale */
137+
result=setlocale(category,locale);
138+
if(!result){
139+
/* operation failed, no setting was changed */
140+
PyErr_SetString(Error,"locale setting not supported");
141+
return NULL;
142+
}
143+
result_object=PyString_FromString(result);
144+
if(!result)return NULL;
145+
/* record changes to LC_NUMERIC */
146+
if(category==LC_NUMERIC || category==LC_ALL){
147+
if(strcmp(locale,"C")==0 || strcmp(locale,"POSIX")==0){
148+
/* user just asked for default numeric locale */
149+
if(saved_numeric)free(saved_numeric);
150+
saved_numeric=0;
151+
}else{
152+
/* remember values */
153+
lc=localeconv();
154+
Py_XDECREF(grouping);
155+
grouping=copy_grouping(lc->grouping);
156+
Py_XDECREF(thousands_sep);
157+
thousands_sep=PyString_FromString(lc->thousands_sep);
158+
Py_XDECREF(decimal_point);
159+
decimal_point=PyString_FromString(lc->decimal_point);
160+
saved_numeric = strdup(locale);
161+
162+
/* restore to "C" */
163+
setlocale(LC_NUMERIC,"C");
164+
}
165+
}
166+
/* record changes to LC_CTYPE */
167+
if(category==LC_CTYPE || category==LC_ALL)
168+
fixup_ulcase();
169+
/* things that got wrong up to here are ignored */
170+
PyErr_Clear();
171+
}else{
172+
/* get locale */
173+
/* restore LC_NUMERIC first, if appropriate */
174+
if(saved_numeric)
175+
setlocale(LC_NUMERIC,saved_numeric);
176+
result=setlocale(category,NULL);
177+
if(!result){
178+
PyErr_SetString(Error,"locale query failed");
179+
return NULL;
180+
}
181+
result_object=PyString_FromString(result);
182+
/* restore back to "C" */
183+
if(saved_numeric)
184+
setlocale(LC_NUMERIC,"C");
185+
}
186+
return result_object;
187+
}
188+
189+
static char localeconv__doc__[]=
190+
"() -> dict. Returns numeric and monetary locale-specific parameters."
191+
;
192+
193+
static PyObject*
194+
PyLocale_localeconv(self,args)
195+
PyObject *self;
196+
PyObject *args;
197+
{
198+
PyObject* result;
199+
struct lconv *l;
200+
PyObject *x;
201+
if(!PyArg_NoArgs(args))return 0;
202+
result = PyDict_New();
203+
if(!result)return 0;
204+
/* if LC_NUMERIC is different in the C library, use saved value */
205+
l = localeconv();
206+
/* hopefully, the localeconv result survives the C library calls
207+
involved herein */
208+
#define RESULT_STRING(s) \
209+
x=PyString_FromString(l->s);if(!x)goto failed;PyDict_SetItemString(result,#s,x);Py_XDECREF(x)
210+
#define RESULT_INT(i) \
211+
x=PyInt_FromLong(l->i);if(!x)goto failed;PyDict_SetItemString(result,#i,x);Py_XDECREF(x)
212+
213+
/* Numeric information */
214+
if(saved_numeric){
215+
/* cannot use localeconv results */
216+
PyDict_SetItemString(result,"decimal_point",decimal_point);
217+
PyDict_SetItemString(result,"grouping",grouping);
218+
PyDict_SetItemString(result,"thousands_sep",thousands_sep);
219+
}else{
220+
RESULT_STRING(decimal_point);
221+
RESULT_STRING(thousands_sep);
222+
x=copy_grouping(l->grouping);
223+
if(!x)goto failed;
224+
PyDict_SetItemString(result,"grouping",x);
225+
Py_XDECREF(x);
226+
}
227+
228+
/* Monetary information */
229+
RESULT_STRING(int_curr_symbol);
230+
RESULT_STRING(currency_symbol);
231+
RESULT_STRING(mon_decimal_point);
232+
RESULT_STRING(mon_thousands_sep);
233+
x=copy_grouping(l->mon_grouping);
234+
if(!x)goto failed;
235+
PyDict_SetItemString(result,"mon_grouping",x);
236+
Py_XDECREF(x);
237+
RESULT_STRING(positive_sign);
238+
RESULT_STRING(negative_sign);
239+
RESULT_INT(int_frac_digits);
240+
RESULT_INT(frac_digits);
241+
RESULT_INT(p_cs_precedes);
242+
RESULT_INT(p_sep_by_space);
243+
RESULT_INT(n_cs_precedes);
244+
RESULT_INT(n_sep_by_space);
245+
RESULT_INT(p_sign_posn);
246+
RESULT_INT(n_sign_posn);
247+
248+
return result;
249+
failed:
250+
Py_XDECREF(result);
251+
Py_XDECREF(x);
252+
return NULL;
253+
}
254+
255+
static char strcoll__doc__[]=
256+
"string,string -> int. Compares two strings according to the locale."
257+
;
258+
259+
static PyObject*
260+
PyLocale_strcoll(self,args)
261+
PyObject *self;
262+
PyObject *args;
263+
{
264+
char *s1,*s2;
265+
if(!PyArg_ParseTuple(args,"ss",&s1,&s2))
266+
return NULL;
267+
return PyInt_FromLong(strcoll(s1,s2));
268+
}
269+
270+
static char strxfrm__doc__[]=
271+
"string -> string. Returns a string that behaves for cmp locale-aware."
272+
;
273+
274+
static PyObject*
275+
PyLocale_strxfrm(self,args)
276+
PyObject* self;
277+
PyObject* args;
278+
{
279+
char *s,*buf;
280+
int n1,n2;
281+
PyObject *result;
282+
if(!PyArg_ParseTuple(args,"s",&s))
283+
return NULL;
284+
/* assume no change in size, first */
285+
n1=strlen(s)+1;
286+
buf=Py_Malloc(n1);
287+
if(!buf)return NULL;
288+
n2=strxfrm(buf,s,n1);
289+
if(n2>n1){
290+
/* more space needed */
291+
buf=Py_Realloc(buf,n2);
292+
if(!buf)return NULL;
293+
strxfrm(buf,s,n2);
294+
}
295+
result=PyString_FromString(buf);
296+
Py_Free(buf);
297+
return result;
298+
}
299+
300+
static struct PyMethodDef PyLocale_Methods[] = {
301+
{"setlocale",(PyCFunction)PyLocale_setlocale,1,setlocale__doc__},
302+
{"localeconv",(PyCFunction)PyLocale_localeconv,0,localeconv__doc__},
303+
{"strcoll",(PyCFunction)PyLocale_strcoll,1,strcoll__doc__},
304+
{"strxfrm",(PyCFunction)PyLocale_strxfrm,1,strxfrm__doc__},
305+
{NULL, NULL}
306+
};
307+
308+
void
309+
init_locale()
310+
{
311+
PyObject *m,*d,*x;
312+
m=Py_InitModule("_locale",PyLocale_Methods);
313+
d = PyModule_GetDict(m);
314+
x=PyInt_FromLong(LC_CTYPE);
315+
PyDict_SetItemString(d,"LC_CTYPE",x);
316+
Py_XDECREF(x);
317+
318+
x=PyInt_FromLong(LC_TIME);
319+
PyDict_SetItemString(d,"LC_TIME",x);
320+
Py_XDECREF(x);
321+
322+
x=PyInt_FromLong(LC_COLLATE);
323+
PyDict_SetItemString(d,"LC_COLLATE",x);
324+
Py_XDECREF(x);
325+
326+
x=PyInt_FromLong(LC_MONETARY);
327+
PyDict_SetItemString(d,"LC_MONETARY",x);
328+
Py_XDECREF(x);
329+
330+
x=PyInt_FromLong(LC_MESSAGES);
331+
PyDict_SetItemString(d,"LC_MESSAGES",x);
332+
Py_XDECREF(x);
333+
334+
x=PyInt_FromLong(LC_NUMERIC);
335+
PyDict_SetItemString(d,"LC_NUMERIC",x);
336+
Py_XDECREF(x);
337+
338+
x=PyInt_FromLong(LC_ALL);
339+
PyDict_SetItemString(d,"LC_ALL",x);
340+
Py_XDECREF(x);
341+
342+
x=PyInt_FromLong(CHAR_MAX);
343+
PyDict_SetItemString(d,"CHAR_MAX",x);
344+
Py_XDECREF(x);
345+
346+
Error = PyErr_NewException("locale.Error", NULL, NULL);
347+
PyDict_SetItemString(d, "Error", Error);
348+
349+
x=PyString_FromString(locale__doc__);
350+
PyDict_SetItemString(d,"__doc__",x);
351+
Py_XDECREF(x);
352+
353+
if(PyErr_Occurred())
354+
Py_FatalError("Can't initialize module locale");
355+
}

0 commit comments

Comments
 (0)