Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
6858cabb
Commit
6858cabb
authored
Feb 23, 2012
by
Brett Cannon
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
dfc32706
41a863cb
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
188 additions
and
151 deletions
+188
-151
Include/unicodeobject.h
Include/unicodeobject.h
+3
-15
Lib/test/test_format.py
Lib/test/test_format.py
+15
-0
Objects/stringlib/asciilib.h
Objects/stringlib/asciilib.h
+0
-3
Objects/stringlib/localeutil.h
Objects/stringlib/localeutil.h
+22
-49
Objects/stringlib/stringdefs.h
Objects/stringlib/stringdefs.h
+0
-2
Objects/stringlib/ucs1lib.h
Objects/stringlib/ucs1lib.h
+0
-3
Objects/stringlib/ucs2lib.h
Objects/stringlib/ucs2lib.h
+0
-3
Objects/stringlib/ucs4lib.h
Objects/stringlib/ucs4lib.h
+0
-3
Objects/stringlib/undef.h
Objects/stringlib/undef.h
+1
-1
Objects/stringlib/unicodedefs.h
Objects/stringlib/unicodedefs.h
+0
-2
Objects/unicodeobject.c
Objects/unicodeobject.c
+58
-17
Python/formatter_unicode.c
Python/formatter_unicode.c
+89
-53
No files found.
Include/unicodeobject.h
View file @
6858cabb
...
...
@@ -1936,32 +1936,20 @@ PyAPI_FUNC(PyObject *) _PyUnicode_XStrip(
);
#endif
/* Using the current locale, insert the thousands grouping
into the string pointed to by buffer. For the argument descriptions,
see Objects/stringlib/localeutil.h */
#ifndef Py_LIMITED_API
PyAPI_FUNC
(
Py_ssize_t
)
_PyUnicode_InsertThousandsGroupingLocale
(
Py_UNICODE
*
buffer
,
Py_ssize_t
n_buffer
,
Py_UNICODE
*
digits
,
Py_ssize_t
n_digits
,
Py_ssize_t
min_width
);
#endif
/* Using explicit passed-in values, insert the thousands grouping
into the string pointed to by buffer. For the argument descriptions,
see Objects/stringlib/localeutil.h */
#ifndef Py_LIMITED_API
PyAPI_FUNC
(
Py_ssize_t
)
_PyUnicode_InsertThousandsGrouping
(
PyObject
*
unicode
,
int
kind
,
void
*
buffer
,
Py_ssize_t
index
,
Py_ssize_t
n_buffer
,
void
*
digits
,
Py_ssize_t
n_digits
,
Py_ssize_t
min_width
,
const
char
*
grouping
,
const
char
*
thousands_sep
);
PyObject
*
thousands_sep
,
Py_UCS4
*
maxchar
);
#endif
/* === Characters Type APIs =============================================== */
...
...
Lib/test/test_format.py
View file @
6858cabb
from
test.support
import
verbose
,
TestFailed
import
locale
import
sys
import
test.support
as
support
import
unittest
...
...
@@ -282,6 +283,20 @@ class FormatTest(unittest.TestCase):
self
.
assertEqual
(
format
(
1
+
2j
,
"
\
u2007
^8"
),
"
\
u2007
(1+2j)
\
u2007
"
)
self
.
assertEqual
(
format
(
0j
,
"
\
u2007
^4"
),
"
\
u2007
0j
\
u2007
"
)
def
test_locale
(
self
):
try
:
oldloc
=
locale
.
setlocale
(
locale
.
LC_ALL
,
''
)
except
locale
.
Error
as
err
:
self
.
skipTest
(
"Cannot set locale: {}"
.
format
(
err
))
try
:
sep
=
locale
.
localeconv
()[
'thousands_sep'
]
text
=
format
(
123456789
,
"n"
)
self
.
assertIn
(
sep
,
text
)
self
.
assertEqual
(
text
.
replace
(
sep
,
''
),
'123456789'
)
finally
:
locale
.
setlocale
(
locale
.
LC_ALL
,
oldloc
)
def
test_main
():
support
.
run_unittest
(
FormatTest
)
...
...
Objects/stringlib/asciilib.h
View file @
6858cabb
...
...
@@ -21,12 +21,9 @@
#define STRINGLIB_RESIZE not_supported
#define STRINGLIB_CHECK PyUnicode_Check
#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact
#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale
#define STRINGLIB_TOSTR PyObject_Str
#define STRINGLIB_TOASCII PyObject_ASCII
#define _Py_InsertThousandsGrouping _PyUnicode_ascii_InsertThousandsGrouping
#define _Py_InsertThousandsGroupingLocale _PyUnicode_ascii_InsertThousandsGroupingLocale
Objects/stringlib/localeutil.h
View file @
6858cabb
...
...
@@ -2,8 +2,9 @@
#include <locale.h>
#define MAX(x, y) ((x) < (y) ? (y) : (x))
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#ifndef STRINGLIB_IS_UNICODE
# error "localeutil is specific to Unicode"
#endif
typedef
struct
{
const
char
*
grouping
;
...
...
@@ -46,7 +47,7 @@ STRINGLIB(GroupGenerator_next)(STRINGLIB(GroupGenerator) *self)
are optional, depending on when we're called. */
static
void
STRINGLIB
(
fill
)(
STRINGLIB_CHAR
**
digits_end
,
STRINGLIB_CHAR
**
buffer_end
,
Py_ssize_t
n_chars
,
Py_ssize_t
n_zeros
,
const
char
*
thousands_sep
,
Py_ssize_t
n_chars
,
Py_ssize_t
n_zeros
,
STRINGLIB_CHAR
*
thousands_sep
,
Py_ssize_t
thousands_sep_len
)
{
Py_ssize_t
i
;
...
...
@@ -55,15 +56,8 @@ STRINGLIB(fill)(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end,
*
buffer_end
-=
thousands_sep_len
;
/* Copy the thousands_sep chars into the buffer. */
#if STRINGLIB_IS_UNICODE
/* Convert from the char's of the thousands_sep from
the locale into unicode. */
for
(
i
=
0
;
i
<
thousands_sep_len
;
++
i
)
(
*
buffer_end
)[
i
]
=
thousands_sep
[
i
];
#else
/* No conversion, just memcpy the thousands_sep. */
memcpy
(
*
buffer_end
,
thousands_sep
,
thousands_sep_len
);
#endif
memcpy
(
*
buffer_end
,
thousands_sep
,
thousands_sep_len
*
STRINGLIB_SIZEOF_CHAR
);
}
*
buffer_end
-=
n_chars
;
...
...
@@ -76,7 +70,7 @@ STRINGLIB(fill)(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end,
}
/**
*
_Py_
InsertThousandsGrouping:
* InsertThousandsGrouping:
* @buffer: A pointer to the start of a string.
* @n_buffer: Number of characters in @buffer.
* @digits: A pointer to the digits we're reading from. If count
...
...
@@ -106,13 +100,15 @@ STRINGLIB(fill)(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end,
_insert_thousands_sep().
**/
Py_ssize_t
_Py_InsertThousandsGrouping
(
STRINGLIB_CHAR
*
buffer
,
STRINGLIB
(
InsertThousandsGrouping
)(
STRINGLIB_CHAR
*
buffer
,
Py_ssize_t
n_buffer
,
STRINGLIB_CHAR
*
digits
,
Py_ssize_t
n_digits
,
Py_ssize_t
min_width
,
const
char
*
grouping
,
const
char
*
thousands_sep
)
STRINGLIB_CHAR
*
thousands_sep
,
Py_ssize_t
thousands_sep_len
)
{
Py_ssize_t
count
=
0
;
Py_ssize_t
n_zeros
;
...
...
@@ -124,7 +120,6 @@ _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer,
STRINGLIB_CHAR
*
digits_end
=
NULL
;
Py_ssize_t
l
;
Py_ssize_t
n_chars
;
Py_ssize_t
thousands_sep_len
=
strlen
(
thousands_sep
);
Py_ssize_t
remaining
=
n_digits
;
/* Number of chars remaining to
be looked at */
/* A generator that returns all of the grouping widths, until it
...
...
@@ -138,9 +133,9 @@ _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer,
}
while
((
l
=
STRINGLIB
(
GroupGenerator_next
)(
&
groupgen
))
>
0
)
{
l
=
MIN
(
l
,
MAX
(
MAX
(
remaining
,
min_width
),
1
));
n_zeros
=
MAX
(
0
,
l
-
remaining
);
n_chars
=
MAX
(
0
,
MIN
(
remaining
,
l
));
l
=
Py_MIN
(
l
,
Py_MAX
(
Py_
MAX
(
remaining
,
min_width
),
1
));
n_zeros
=
Py_
MAX
(
0
,
l
-
remaining
);
n_chars
=
Py_MAX
(
0
,
Py_
MIN
(
remaining
,
l
));
/* Use n_zero zero's and n_chars chars */
...
...
@@ -168,9 +163,9 @@ _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer,
if
(
!
loop_broken
)
{
/* We left the loop without using a break statement. */
l
=
MAX
(
MAX
(
remaining
,
min_width
),
1
);
n_zeros
=
MAX
(
0
,
l
-
remaining
);
n_chars
=
MAX
(
0
,
MIN
(
remaining
,
l
));
l
=
Py_MAX
(
Py_
MAX
(
remaining
,
min_width
),
1
);
n_zeros
=
Py_
MAX
(
0
,
l
-
remaining
);
n_chars
=
Py_MAX
(
0
,
Py_
MIN
(
remaining
,
l
));
/* Use n_zero zero's and n_chars chars */
count
+=
(
use_separator
?
thousands_sep_len
:
0
)
+
n_zeros
+
n_chars
;
...
...
@@ -183,25 +178,3 @@ _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer,
return
count
;
}
/**
* _Py_InsertThousandsGroupingLocale:
* @buffer: A pointer to the start of a string.
* @n_digits: The number of digits in the string, in which we want
* to put the grouping chars.
*
* Reads thee current locale and calls _Py_InsertThousandsGrouping().
**/
Py_ssize_t
_Py_InsertThousandsGroupingLocale
(
STRINGLIB_CHAR
*
buffer
,
Py_ssize_t
n_buffer
,
STRINGLIB_CHAR
*
digits
,
Py_ssize_t
n_digits
,
Py_ssize_t
min_width
)
{
struct
lconv
*
locale_data
=
localeconv
();
const
char
*
grouping
=
locale_data
->
grouping
;
const
char
*
thousands_sep
=
locale_data
->
thousands_sep
;
return
_Py_InsertThousandsGrouping
(
buffer
,
n_buffer
,
digits
,
n_digits
,
min_width
,
grouping
,
thousands_sep
);
}
Objects/stringlib/stringdefs.h
View file @
6858cabb
...
...
@@ -25,7 +25,5 @@
#define STRINGLIB_CHECK PyBytes_Check
#define STRINGLIB_CHECK_EXACT PyBytes_CheckExact
#define STRINGLIB_TOSTR PyObject_Str
#define STRINGLIB_GROUPING _PyBytes_InsertThousandsGrouping
#define STRINGLIB_GROUPING_LOCALE _PyBytes_InsertThousandsGroupingLocale
#define STRINGLIB_TOASCII PyObject_Repr
#endif
/* !STRINGLIB_STRINGDEFS_H */
Objects/stringlib/ucs1lib.h
View file @
6858cabb
...
...
@@ -21,13 +21,10 @@
#define STRINGLIB_RESIZE not_supported
#define STRINGLIB_CHECK PyUnicode_Check
#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact
#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale
#define STRINGLIB_TOSTR PyObject_Str
#define STRINGLIB_TOASCII PyObject_ASCII
#define _Py_InsertThousandsGrouping _PyUnicode_ucs1_InsertThousandsGrouping
#define _Py_InsertThousandsGroupingLocale _PyUnicode_ucs1_InsertThousandsGroupingLocale
Objects/stringlib/ucs2lib.h
View file @
6858cabb
...
...
@@ -21,12 +21,9 @@
#define STRINGLIB_RESIZE not_supported
#define STRINGLIB_CHECK PyUnicode_Check
#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact
#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale
#define STRINGLIB_TOSTR PyObject_Str
#define STRINGLIB_TOASCII PyObject_ASCII
#define _Py_InsertThousandsGrouping _PyUnicode_ucs2_InsertThousandsGrouping
#define _Py_InsertThousandsGroupingLocale _PyUnicode_ucs2_InsertThousandsGroupingLocale
Objects/stringlib/ucs4lib.h
View file @
6858cabb
...
...
@@ -21,12 +21,9 @@
#define STRINGLIB_RESIZE not_supported
#define STRINGLIB_CHECK PyUnicode_Check
#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact
#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale
#define STRINGLIB_TOSTR PyObject_Str
#define STRINGLIB_TOASCII PyObject_ASCII
#define _Py_InsertThousandsGrouping _PyUnicode_ucs4_InsertThousandsGrouping
#define _Py_InsertThousandsGroupingLocale _PyUnicode_ucs4_InsertThousandsGroupingLocale
Objects/stringlib/undef.h
View file @
6858cabb
...
...
@@ -7,5 +7,5 @@
#undef STRINGLIB_NEW
#undef STRINGLIB_RESIZE
#undef _Py_InsertThousandsGrouping
#undef
_Py_InsertThousandsGroupingLocale
#undef
STRINGLIB_IS_UNICODE
Objects/stringlib/unicodedefs.h
View file @
6858cabb
...
...
@@ -24,8 +24,6 @@
#define STRINGLIB_RESIZE PyUnicode_Resize
#define STRINGLIB_CHECK PyUnicode_Check
#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact
#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale
#if PY_VERSION_HEX < 0x03000000
#define STRINGLIB_TOSTR PyObject_Unicode
...
...
Objects/unicodeobject.c
View file @
6858cabb
...
...
@@ -9151,34 +9151,75 @@ any_find_slice(int direction, PyObject* s1, PyObject* s2,
}
Py_ssize_t
_PyUnicode_InsertThousandsGrouping
(
PyObject
*
unicode
,
int
kind
,
void
*
data
,
_PyUnicode_InsertThousandsGrouping
(
PyObject
*
unicode
,
Py_ssize_t
index
,
Py_ssize_t
n_buffer
,
void
*
digits
,
Py_ssize_t
n_digits
,
Py_ssize_t
min_width
,
const
char
*
grouping
,
const
char
*
thousands_sep
)
const
char
*
grouping
,
PyObject
*
thousands_sep
,
Py_UCS4
*
maxchar
)
{
unsigned
int
kind
,
thousands_sep_kind
;
void
*
data
,
*
thousands_sep_data
;
Py_ssize_t
thousands_sep_len
;
Py_ssize_t
len
;
if
(
unicode
!=
NULL
)
{
kind
=
PyUnicode_KIND
(
unicode
);
data
=
PyUnicode_DATA
(
unicode
)
+
index
*
kind
;
}
else
{
kind
=
PyUnicode_1BYTE_KIND
;
data
=
NULL
;
}
thousands_sep_kind
=
PyUnicode_KIND
(
thousands_sep
);
thousands_sep_data
=
PyUnicode_DATA
(
thousands_sep
);
thousands_sep_len
=
PyUnicode_GET_LENGTH
(
thousands_sep
);
if
(
unicode
!=
NULL
&&
thousands_sep_kind
!=
kind
)
{
thousands_sep_data
=
_PyUnicode_AsKind
(
thousands_sep
,
kind
);
if
(
!
thousands_sep_data
)
return
-
1
;
}
switch
(
kind
)
{
case
PyUnicode_1BYTE_KIND
:
if
(
unicode
!=
NULL
&&
PyUnicode_IS_ASCII
(
unicode
))
return
_PyUnicode_ascii
_InsertThousandsGrouping
(
len
=
asciilib
_InsertThousandsGrouping
(
(
Py_UCS1
*
)
data
,
n_buffer
,
(
Py_UCS1
*
)
digits
,
n_digits
,
min_width
,
grouping
,
thousands_sep
);
min_width
,
grouping
,
thousands_sep_data
,
thousands_sep_len
);
else
return
_PyUnicode_ucs1
_InsertThousandsGrouping
(
len
=
ucs1lib
_InsertThousandsGrouping
(
(
Py_UCS1
*
)
data
,
n_buffer
,
(
Py_UCS1
*
)
digits
,
n_digits
,
min_width
,
grouping
,
thousands_sep
);
min_width
,
grouping
,
thousands_sep_data
,
thousands_sep_len
);
break
;
case
PyUnicode_2BYTE_KIND
:
return
_PyUnicode_ucs2
_InsertThousandsGrouping
(
len
=
ucs2lib
_InsertThousandsGrouping
(
(
Py_UCS2
*
)
data
,
n_buffer
,
(
Py_UCS2
*
)
digits
,
n_digits
,
min_width
,
grouping
,
thousands_sep
);
min_width
,
grouping
,
thousands_sep_data
,
thousands_sep_len
);
break
;
case
PyUnicode_4BYTE_KIND
:
return
_PyUnicode_ucs4
_InsertThousandsGrouping
(
len
=
ucs4lib
_InsertThousandsGrouping
(
(
Py_UCS4
*
)
data
,
n_buffer
,
(
Py_UCS4
*
)
digits
,
n_digits
,
min_width
,
grouping
,
thousands_sep
);
}
min_width
,
grouping
,
thousands_sep_data
,
thousands_sep_len
);
break
;
default:
assert
(
0
);
return
-
1
;
}
if
(
unicode
!=
NULL
&&
thousands_sep_kind
!=
kind
)
PyMem_Free
(
thousands_sep_data
);
if
(
unicode
==
NULL
)
{
*
maxchar
=
127
;
if
(
len
!=
n_digits
)
{
*
maxchar
=
Py_MAX
(
*
maxchar
,
PyUnicode_MAX_CHAR_VALUE
(
thousands_sep
));
}
}
return
len
;
}
...
...
Python/formatter_unicode.c
View file @
6858cabb
...
...
@@ -346,11 +346,13 @@ fill_padding(PyObject *s, Py_ssize_t start, Py_ssize_t nchars,
before and including the decimal. Note that locales only support
8-bit chars, not unicode. */
typedef
struct
{
char
*
decimal_point
;
char
*
thousands_sep
;
char
*
grouping
;
PyObject
*
decimal_point
;
PyObject
*
thousands_sep
;
c
onst
c
har
*
grouping
;
}
LocaleInfo
;
#define STATIC_LOCALE_INFO_INIT {0, 0, 0}
/* describes the layout for an integer, see the comment in
calc_number_widths() for details */
typedef
struct
{
...
...
@@ -415,7 +417,7 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
Py_UCS4
sign_char
,
PyObject
*
number
,
Py_ssize_t
n_start
,
Py_ssize_t
n_end
,
Py_ssize_t
n_remainder
,
int
has_decimal
,
const
LocaleInfo
*
locale
,
const
InternalFormatSpec
*
format
)
const
InternalFormatSpec
*
format
,
Py_UCS4
*
maxchar
)
{
Py_ssize_t
n_non_digit_non_padding
;
Py_ssize_t
n_padding
;
...
...
@@ -423,7 +425,7 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
spec
->
n_digits
=
n_end
-
n_start
-
n_remainder
-
(
has_decimal
?
1
:
0
);
spec
->
n_lpadding
=
0
;
spec
->
n_prefix
=
n_prefix
;
spec
->
n_decimal
=
has_decimal
?
strlen
(
locale
->
decimal_point
)
:
0
;
spec
->
n_decimal
=
has_decimal
?
PyUnicode_GET_LENGTH
(
locale
->
decimal_point
)
:
0
;
spec
->
n_remainder
=
n_remainder
;
spec
->
n_spadding
=
0
;
spec
->
n_rpadding
=
0
;
...
...
@@ -484,11 +486,15 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
to special case it because the grouping code always wants
to have at least one character. */
spec
->
n_grouped_digits
=
0
;
else
else
{
Py_UCS4
grouping_maxchar
;
spec
->
n_grouped_digits
=
_PyUnicode_InsertThousandsGrouping
(
NULL
,
PyUnicode_1BYTE_KIND
,
NULL
,
0
,
NULL
,
NULL
,
0
,
0
,
NULL
,
spec
->
n_digits
,
spec
->
n_min_width
,
locale
->
grouping
,
locale
->
thousands_sep
);
locale
->
grouping
,
locale
->
thousands_sep
,
&
grouping_maxchar
);
*
maxchar
=
Py_MAX
(
*
maxchar
,
grouping_maxchar
);
}
/* Given the desired width and the total of digit and non-digit
space we consume, see if we need any padding. format->width can
...
...
@@ -519,6 +525,10 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
break
;
}
}
if
(
spec
->
n_lpadding
||
spec
->
n_spadding
||
spec
->
n_rpadding
)
*
maxchar
=
Py_MAX
(
*
maxchar
,
format
->
fill_char
);
return
spec
->
n_lpadding
+
spec
->
n_sign
+
spec
->
n_prefix
+
spec
->
n_spadding
+
spec
->
n_grouped_digits
+
spec
->
n_decimal
+
spec
->
n_remainder
+
spec
->
n_rpadding
;
...
...
@@ -587,12 +597,11 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
r
=
#endif
_PyUnicode_InsertThousandsGrouping
(
out
,
kind
,
(
char
*
)
data
+
kind
*
pos
,
out
,
pos
,
spec
->
n_grouped_digits
,
pdigits
+
kind
*
d_pos
,
spec
->
n_digits
,
spec
->
n_min_width
,
locale
->
grouping
,
locale
->
thousands_sep
);
locale
->
grouping
,
locale
->
thousands_sep
,
NULL
);
#ifndef NDEBUG
assert
(
r
==
spec
->
n_grouped_digits
);
#endif
...
...
@@ -615,10 +624,8 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
pos
+=
spec
->
n_grouped_digits
;
if
(
spec
->
n_decimal
)
{
Py_ssize_t
t
;
for
(
t
=
0
;
t
<
spec
->
n_decimal
;
++
t
)
PyUnicode_WRITE
(
kind
,
data
,
pos
+
t
,
locale
->
decimal_point
[
t
]);
if
(
PyUnicode_CopyCharacters
(
out
,
pos
,
locale
->
decimal_point
,
0
,
spec
->
n_decimal
)
<
0
)
return
-
1
;
pos
+=
spec
->
n_decimal
;
d_pos
+=
1
;
}
...
...
@@ -643,32 +650,60 @@ static char no_grouping[1] = {CHAR_MAX};
grouping description, either for the current locale if type is
LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or
none if LT_NO_LOCALE. */
static
void
static
int
get_locale_info
(
int
type
,
LocaleInfo
*
locale_info
)
{
switch
(
type
)
{
case
LT_CURRENT_LOCALE
:
{
struct
lconv
*
locale_data
=
localeconv
();
locale_info
->
decimal_point
=
locale_data
->
decimal_point
;
locale_info
->
thousands_sep
=
locale_data
->
thousands_sep
;
locale_info
->
decimal_point
=
PyUnicode_DecodeLocale
(
locale_data
->
decimal_point
,
NULL
);
if
(
locale_info
->
decimal_point
==
NULL
)
return
-
1
;
locale_info
->
thousands_sep
=
PyUnicode_DecodeLocale
(
locale_data
->
thousands_sep
,
NULL
);
if
(
locale_info
->
thousands_sep
==
NULL
)
{
Py_DECREF
(
locale_info
->
decimal_point
);
return
-
1
;
}
locale_info
->
grouping
=
locale_data
->
grouping
;
break
;
}
case
LT_DEFAULT_LOCALE
:
locale_info
->
decimal_point
=
"."
;
locale_info
->
thousands_sep
=
","
;
locale_info
->
decimal_point
=
PyUnicode_FromOrdinal
(
'.'
);
locale_info
->
thousands_sep
=
PyUnicode_FromOrdinal
(
','
);
if
(
!
locale_info
->
decimal_point
||
!
locale_info
->
thousands_sep
)
{
Py_XDECREF
(
locale_info
->
decimal_point
);
Py_XDECREF
(
locale_info
->
thousands_sep
);
return
-
1
;
}
locale_info
->
grouping
=
"
\3
"
;
/* Group every 3 characters. The
(implicit) trailing 0 means repeat
infinitely. */
break
;
case
LT_NO_LOCALE
:
locale_info
->
decimal_point
=
"."
;
locale_info
->
thousands_sep
=
""
;
locale_info
->
decimal_point
=
PyUnicode_FromOrdinal
(
'.'
);
locale_info
->
thousands_sep
=
PyUnicode_New
(
0
,
0
);
if
(
!
locale_info
->
decimal_point
||
!
locale_info
->
thousands_sep
)
{
Py_XDECREF
(
locale_info
->
decimal_point
);
Py_XDECREF
(
locale_info
->
thousands_sep
);
return
-
1
;
}
locale_info
->
grouping
=
no_grouping
;
break
;
default:
assert
(
0
);
}
return
0
;
}
static
void
free_locale_info
(
LocaleInfo
*
locale_info
)
{
Py_XDECREF
(
locale_info
->
decimal_point
);
Py_XDECREF
(
locale_info
->
thousands_sep
);
}
/************************************************************************/
...
...
@@ -769,7 +804,7 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
/* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */
LocaleInfo
locale
;
LocaleInfo
locale
=
STATIC_LOCALE_INFO_INIT
;
/* no precision allowed on integers */
if
(
format
->
precision
!=
-
1
)
{
...
...
@@ -868,18 +903,17 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
}
/* Determine the grouping, separator, and decimal point, if any. */
get_locale_info
(
format
->
type
==
'n'
?
LT_CURRENT_LOCALE
:
if
(
get_locale_info
(
format
->
type
==
'n'
?
LT_CURRENT_LOCALE
:
(
format
->
thousands_separators
?
LT_DEFAULT_LOCALE
:
LT_NO_LOCALE
),
&
locale
);
&
locale
)
==
-
1
)
goto
done
;
/* Calculate how much memory we'll need. */
n_total
=
calc_number_widths
(
&
spec
,
n_prefix
,
sign_char
,
tmp
,
inumeric_chars
,
inumeric_chars
+
n_digits
,
n_remainder
,
0
,
&
locale
,
format
);
if
(
spec
.
n_lpadding
||
spec
.
n_spadding
||
spec
.
n_rpadding
)
maxchar
=
Py_MAX
(
maxchar
,
format
->
fill_char
);
inumeric_chars
+
n_digits
,
n_remainder
,
0
,
&
locale
,
format
,
&
maxchar
);
/* Allocate the memory. */
result
=
PyUnicode_New
(
n_total
,
maxchar
);
...
...
@@ -897,6 +931,7 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
done:
Py_XDECREF
(
tmp
);
free_locale_info
(
&
locale
);
assert
(
!
result
||
_PyUnicode_CheckConsistency
(
result
,
1
));
return
result
;
}
...
...
@@ -938,7 +973,7 @@ format_float_internal(PyObject *value,
/* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */
LocaleInfo
locale
;
LocaleInfo
locale
=
STATIC_LOCALE_INFO_INIT
;
if
(
format
->
alternate
)
flags
|=
Py_DTSF_ALT
;
...
...
@@ -1009,19 +1044,17 @@ format_float_internal(PyObject *value,
parse_number
(
unicode_tmp
,
index
,
index
+
n_digits
,
&
n_remainder
,
&
has_decimal
);
/* Determine the grouping, separator, and decimal point, if any. */
get_locale_info
(
format
->
type
==
'n'
?
LT_CURRENT_LOCALE
:
if
(
get_locale_info
(
format
->
type
==
'n'
?
LT_CURRENT_LOCALE
:
(
format
->
thousands_separators
?
LT_DEFAULT_LOCALE
:
LT_NO_LOCALE
),
&
locale
);
&
locale
)
==
-
1
)
goto
done
;
/* Calculate how much memory we'll need. */
n_total
=
calc_number_widths
(
&
spec
,
0
,
sign_char
,
unicode_tmp
,
index
,
index
+
n_digits
,
n_remainder
,
has_decimal
,
&
locale
,
format
);
if
(
spec
.
n_lpadding
||
spec
.
n_spadding
||
spec
.
n_rpadding
)
maxchar
=
Py_MAX
(
maxchar
,
format
->
fill_char
);
&
locale
,
format
,
&
maxchar
);
/* Allocate the memory. */
result
=
PyUnicode_New
(
n_total
,
maxchar
);
...
...
@@ -1040,6 +1073,7 @@ format_float_internal(PyObject *value,
done:
PyMem_Free
(
buf
);
Py_DECREF
(
unicode_tmp
);
free_locale_info
(
&
locale
);
assert
(
!
result
||
_PyUnicode_CheckConsistency
(
result
,
1
));
return
result
;
}
...
...
@@ -1094,7 +1128,7 @@ format_complex_internal(PyObject *value,
/* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */
LocaleInfo
locale
;
LocaleInfo
locale
=
STATIC_LOCALE_INFO_INIT
;
/* Zero padding is not allowed. */
if
(
format
->
fill_char
==
'0'
)
{
...
...
@@ -1190,11 +1224,12 @@ format_complex_internal(PyObject *value,
&
n_im_remainder
,
&
im_has_decimal
);
/* Determine the grouping, separator, and decimal point, if any. */
get_locale_info
(
format
->
type
==
'n'
?
LT_CURRENT_LOCALE
:
if
(
get_locale_info
(
format
->
type
==
'n'
?
LT_CURRENT_LOCALE
:
(
format
->
thousands_separators
?
LT_DEFAULT_LOCALE
:
LT_NO_LOCALE
),
&
locale
);
&
locale
)
==
-
1
)
goto
done
;
/* Turn off any padding. We'll do it later after we've composed
the numbers without padding. */
...
...
@@ -1205,7 +1240,8 @@ format_complex_internal(PyObject *value,
/* Calculate how much memory we'll need. */
n_re_total
=
calc_number_widths
(
&
re_spec
,
0
,
re_sign_char
,
re_unicode_tmp
,
i_re
,
i_re
+
n_re_digits
,
n_re_remainder
,
re_has_decimal
,
&
locale
,
&
tmp_format
);
re_has_decimal
,
&
locale
,
&
tmp_format
,
&
maxchar
);
/* Same formatting, but always include a sign, unless the real part is
* going to be omitted, in which case we use whatever sign convention was
...
...
@@ -1214,7 +1250,8 @@ format_complex_internal(PyObject *value,
tmp_format
.
sign
=
'+'
;
n_im_total
=
calc_number_widths
(
&
im_spec
,
0
,
im_sign_char
,
im_unicode_tmp
,
i_im
,
i_im
+
n_im_digits
,
n_im_remainder
,
im_has_decimal
,
&
locale
,
&
tmp_format
);
im_has_decimal
,
&
locale
,
&
tmp_format
,
&
maxchar
);
if
(
skip_re
)
n_re_total
=
0
;
...
...
@@ -1223,9 +1260,7 @@ format_complex_internal(PyObject *value,
calc_padding
(
n_re_total
+
n_im_total
+
1
+
add_parens
*
2
,
format
->
width
,
format
->
align
,
&
lpad
,
&
rpad
,
&
total
);
if
(
re_spec
.
n_lpadding
||
re_spec
.
n_spadding
||
re_spec
.
n_rpadding
||
im_spec
.
n_lpadding
||
im_spec
.
n_spadding
||
im_spec
.
n_rpadding
||
lpad
||
rpad
)
if
(
lpad
||
rpad
)
maxchar
=
Py_MAX
(
maxchar
,
format
->
fill_char
);
result
=
PyUnicode_New
(
total
,
maxchar
);
...
...
@@ -1275,6 +1310,7 @@ done:
PyMem_Free
(
im_buf
);
Py_XDECREF
(
re_unicode_tmp
);
Py_XDECREF
(
im_unicode_tmp
);
free_locale_info
(
&
locale
);
assert
(
!
result
||
_PyUnicode_CheckConsistency
(
result
,
1
));
return
result
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment