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
82864d1a
Commit
82864d1a
authored
Nov 15, 2009
by
Mark Dickinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #7228: Add '%lld' and '%llu' support to PyFormat_FromString,
PyFormat_FromStringV and PyErr_Format.
parent
d5b34d45
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
266 additions
and
13 deletions
+266
-13
Doc/c-api/exceptions.rst
Doc/c-api/exceptions.rst
+16
-0
Doc/c-api/string.rst
Doc/c-api/string.rst
+16
-0
Include/pyport.h
Include/pyport.h
+16
-0
Misc/NEWS
Misc/NEWS
+3
-0
Modules/_testcapimodule.c
Modules/_testcapimodule.c
+6
-0
Objects/stringobject.c
Objects/stringobject.c
+59
-12
configure
configure
+99
-1
configure.in
configure.in
+48
-0
pyconfig.h.in
pyconfig.h.in
+3
-0
No files found.
Doc/c-api/exceptions.rst
View file @
82864d1a
...
...
@@ -161,6 +161,8 @@ is a separate error indicator for each thread.
.. % The descriptions for %zd and %zu are wrong, but the truth is complicated
.. % because not all compilers support the %z width modifier -- we fake it
.. % when necessary via interpolating PY_FORMAT_SIZE_T.
.. % Similar comments apply to the %ll width modifier and
.. % PY_FORMAT_LONG_LONG.
.. % %u, %lu, %zu should have "new in Python 2.5" blurbs.
+-------------------+---------------+--------------------------------+
...
...
@@ -183,6 +185,12 @@ is a separate error indicator for each thread.
| :attr:`%lu` | unsigned long | Exactly equivalent to |
| | | ``printf("%lu")``. |
+-------------------+---------------+--------------------------------+
| :attr:`%lld` | long long | Exactly equivalent to |
| | | ``printf("%lld")``. |
+-------------------+---------------+--------------------------------+
| :attr:`%llu` | unsigned | Exactly equivalent to |
| | long long | ``printf("%llu")``. |
+-------------------+---------------+--------------------------------+
| :attr:`%zd` | Py_ssize_t | Exactly equivalent to |
| | | ``printf("%zd")``. |
+-------------------+---------------+--------------------------------+
...
...
@@ -210,6 +218,14 @@ is a separate error indicator for each thread.
An unrecognized format character causes all the rest of the format string to be
copied as-is to the result string, and any extra arguments discarded.
.. note::
The `"%lld"` and `"%llu"` format specifiers are only available
when `HAVE_LONG_LONG` is defined.
.. versionchanged:: 2.7
Support for `"%lld"` and `"%llu"` added.
.. cfunction:: void PyErr_SetNone(PyObject *type)
...
...
Doc/c-api/string.rst
View file @
82864d1a
...
...
@@ -78,6 +78,8 @@ called with a non-string parameter.
.. % The descriptions for %zd and %zu are wrong, but the truth is complicated
.. % because not all compilers support the %z width modifier -- we fake it
.. % when necessary via interpolating PY_FORMAT_SIZE_T.
.. % Similar comments apply to the %ll width modifier and
.. % PY_FORMAT_LONG_LONG.
.. % %u, %lu, %zu should have "new in Python 2.5" blurbs.
+-------------------+---------------+--------------------------------+
...
...
@@ -100,6 +102,12 @@ called with a non-string parameter.
| :attr:`%lu` | unsigned long | Exactly equivalent to |
| | | ``printf("%lu")``. |
+-------------------+---------------+--------------------------------+
| :attr:`%lld` | long long | Exactly equivalent to |
| | | ``printf("%lld")``. |
+-------------------+---------------+--------------------------------+
| :attr:`%llu` | unsigned | Exactly equivalent to |
| | long long | ``printf("%llu")``. |
+-------------------+---------------+--------------------------------+
| :attr:`%zd` | Py_ssize_t | Exactly equivalent to |
| | | ``printf("%zd")``. |
+-------------------+---------------+--------------------------------+
...
...
@@ -127,6 +135,14 @@ called with a non-string parameter.
An unrecognized format character causes all the rest of the format string to be
copied as-is to the result string, and any extra arguments discarded.
.. note::
The `"%lld"` and `"%llu"` format specifiers are only available
when `HAVE_LONG_LONG` is defined.
.. versionchanged:: 2.7
Support for `"%lld"` and `"%llu"` added.
.. cfunction:: PyObject* PyString_FromFormatV(const char *format, va_list vargs)
...
...
Include/pyport.h
View file @
82864d1a
...
...
@@ -229,6 +229,22 @@ typedef Py_intptr_t Py_ssize_t;
# endif
#endif
/* PY_FORMAT_LONG_LONG is analogous to PY_FORMAT_SIZE_T above, but for
* the long long type instead of the size_t type. It's only available
* when HAVE_LONG_LONG is defined. The "high level" Python format
* functions listed above will interpret "lld" or "llu" correctly on
* all platforms.
*/
#ifdef HAVE_LONG_LONG
# ifndef PY_FORMAT_LONG_LONG
# if defined(MS_WIN64) || defined(MS_WINDOWS)
# define PY_FORMAT_LONG_LONG "I64"
# else
# error "This platform's pyconfig.h needs to define PY_FORMAT_LONG_LONG"
# endif
# endif
#endif
/* Py_LOCAL can be used instead of static to get the fastest possible calling
* convention for functions that are local to a given module.
*
...
...
Misc/NEWS
View file @
82864d1a
...
...
@@ -1462,6 +1462,9 @@ Documentation
C-API
-----
- Issue #Add '%lld' and '%llu' support to PyString_FromFormat(V)
and PyErr_Format, on machines with HAVE_LONG_LONG defined.
- Add new C-API function PyOS_string_to_double, and deprecated
PyOS_ascii_atof and PyOS_ascii_strtod.
...
...
Modules/_testcapimodule.c
View file @
82864d1a
...
...
@@ -954,6 +954,12 @@ test_string_from_format(PyObject *self, PyObject *args)
CHECK_1_FORMAT
(
"%lu"
,
unsigned
long
);
CHECK_1_FORMAT
(
"%zu"
,
size_t
);
/* "%lld" and "%llu" support added in Python 2.7. */
#ifdef HAVE_LONG_LONG
CHECK_1_FORMAT
(
"%llu"
,
unsigned
PY_LONG_LONG
);
CHECK_1_FORMAT
(
"%lld"
,
PY_LONG_LONG
);
#endif
Py_RETURN_NONE
;
Fail:
...
...
Objects/stringobject.c
View file @
82864d1a
...
...
@@ -189,6 +189,9 @@ PyString_FromFormatV(const char *format, va_list vargs)
/* step 1: figure out how large a buffer we need */
for
(
f
=
format
;
*
f
;
f
++
)
{
if
(
*
f
==
'%'
)
{
#ifdef HAVE_LONG_LONG
int
longlongflag
=
0
;
#endif
const
char
*
p
=
f
;
while
(
*++
f
&&
*
f
!=
'%'
&&
!
isalpha
(
Py_CHARMASK
(
*
f
)))
;
...
...
@@ -196,9 +199,21 @@ PyString_FromFormatV(const char *format, va_list vargs)
/* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
* they don't affect the amount of space we reserve.
*/
if
((
*
f
==
'l'
||
*
f
==
'z'
)
&&
(
f
[
1
]
==
'd'
||
f
[
1
]
==
'u'
))
if
(
*
f
==
'l'
)
{
if
(
f
[
1
]
==
'd'
||
f
[
1
]
==
'u'
)
{
++
f
;
}
#ifdef HAVE_LONG_LONG
else
if
(
f
[
1
]
==
'l'
&&
(
f
[
2
]
==
'd'
||
f
[
2
]
==
'u'
))
{
longlongflag
=
1
;
f
+=
2
;
}
#endif
}
else
if
(
*
f
==
'z'
&&
(
f
[
1
]
==
'd'
||
f
[
1
]
==
'u'
))
{
++
f
;
}
switch
(
*
f
)
{
case
'c'
:
...
...
@@ -209,10 +224,21 @@ PyString_FromFormatV(const char *format, va_list vargs)
break
;
case
'd'
:
case
'u'
:
case
'i'
:
case
'x'
:
(
void
)
va_arg
(
count
,
int
);
/* 20 bytes is enough to hold a 64-bit
integer. Decimal takes the most space.
This isn't enough for octal. */
n
+=
20
;
#ifdef HAVE_LONG_LONG
/* Need at most
ceil(log10(256)*SIZEOF_LONG_LONG) digits,
plus 1 for the sign. 53/22 is an upper
bound for log10(256). */
if
(
longlongflag
)
n
+=
2
+
(
SIZEOF_LONG_LONG
*
53
-
1
)
/
22
;
else
#endif
/* 20 bytes is enough to hold a 64-bit
integer. Decimal takes the most
space. This isn't enough for
octal. */
n
+=
20
;
break
;
case
's'
:
s
=
va_arg
(
count
,
char
*
);
...
...
@@ -255,6 +281,9 @@ PyString_FromFormatV(const char *format, va_list vargs)
const
char
*
p
=
f
++
;
Py_ssize_t
i
;
int
longflag
=
0
;
#ifdef HAVE_LONG_LONG
int
longlongflag
=
0
;
#endif
int
size_tflag
=
0
;
/* parse the width.precision part (we're only
interested in the precision value, if any) */
...
...
@@ -269,14 +298,22 @@ PyString_FromFormatV(const char *format, va_list vargs)
}
while
(
*
f
&&
*
f
!=
'%'
&&
!
isalpha
(
Py_CHARMASK
(
*
f
)))
f
++
;
/* handle the long flag, but only for %ld and %lu.
others can be added when necessary. */
if
(
*
f
==
'l'
&&
(
f
[
1
]
==
'd'
||
f
[
1
]
==
'u'
))
{
longflag
=
1
;
++
f
;
/* Handle %ld, %lu, %lld and %llu. */
if
(
*
f
==
'l'
)
{
if
(
f
[
1
]
==
'd'
||
f
[
1
]
==
'u'
)
{
longflag
=
1
;
++
f
;
}
#ifdef HAVE_LONG_LONG
else
if
(
f
[
1
]
==
'l'
&&
(
f
[
2
]
==
'd'
||
f
[
2
]
==
'u'
))
{
longlongflag
=
1
;
f
+=
2
;
}
#endif
}
/* handle the size_t flag. */
if
(
*
f
==
'z'
&&
(
f
[
1
]
==
'd'
||
f
[
1
]
==
'u'
))
{
else
if
(
*
f
==
'z'
&&
(
f
[
1
]
==
'd'
||
f
[
1
]
==
'u'
))
{
size_tflag
=
1
;
++
f
;
}
...
...
@@ -288,6 +325,11 @@ PyString_FromFormatV(const char *format, va_list vargs)
case
'd'
:
if
(
longflag
)
sprintf
(
s
,
"%ld"
,
va_arg
(
vargs
,
long
));
#ifdef HAVE_LONG_LONG
else
if
(
longlongflag
)
sprintf
(
s
,
"%"
PY_FORMAT_LONG_LONG
"d"
,
va_arg
(
vargs
,
PY_LONG_LONG
));
#endif
else
if
(
size_tflag
)
sprintf
(
s
,
"%"
PY_FORMAT_SIZE_T
"d"
,
va_arg
(
vargs
,
Py_ssize_t
));
...
...
@@ -299,6 +341,11 @@ PyString_FromFormatV(const char *format, va_list vargs)
if
(
longflag
)
sprintf
(
s
,
"%lu"
,
va_arg
(
vargs
,
unsigned
long
));
#ifdef HAVE_LONG_LONG
else
if
(
longlongflag
)
sprintf
(
s
,
"%"
PY_FORMAT_LONG_LONG
"u"
,
va_arg
(
vargs
,
PY_LONG_LONG
));
#endif
else
if
(
size_tflag
)
sprintf
(
s
,
"%"
PY_FORMAT_SIZE_T
"u"
,
va_arg
(
vargs
,
size_t
));
...
...
configure
View file @
82864d1a
#! /bin/sh
# From configure.in Revision: 76
052
.
# From configure.in Revision: 76
300
.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for python 2.7.
#
...
...
@@ -27014,6 +27014,104 @@ else
echo
"
${
ECHO_T
}
no"
>
&6
;
}
fi
if
test
"
$have_long_long
"
=
yes
then
{
echo
"
$as_me
:
$LINENO
: checking for %lld and %llu printf() format support"
>
&5
echo
$ECHO_N
"checking for %lld and %llu printf() format support...
$ECHO_C
"
>
&6
;
}
if
test
"
${
ac_cv_have_long_long_format
+set
}
"
=
set
;
then
echo
$ECHO_N
"(cached)
$ECHO_C
"
>
&6
else
if
test
"
$cross_compiling
"
=
yes
;
then
ac_cv_have_long_long_format
=
no
else
cat
>
conftest.
$ac_ext
<<
_ACEOF
/* confdefs.h. */
_ACEOF
cat
confdefs.h
>>
conftest.
$ac_ext
cat
>>
conftest.
$ac_ext
<<
_ACEOF
/* end confdefs.h. */
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
int main()
{
char buffer[256];
if (sprintf(buffer, "%lld", (long long)123) < 0)
return 1;
if (strcmp(buffer, "123"))
return 1;
if (sprintf(buffer, "%lld", (long long)-123) < 0)
return 1;
if (strcmp(buffer, "-123"))
return 1;
if (sprintf(buffer, "%llu", (unsigned long long)123) < 0)
return 1;
if (strcmp(buffer, "123"))
return 1;
return 0;
}
_ACEOF
rm
-f
conftest
$ac_exeext
if
{
(
ac_try
=
"
$ac_link
"
case
"((
$ac_try
"
in
*
\"
*
|
*
\`
*
|
*
\\
*
)
ac_try_echo
=
\$
ac_try
;;
*
)
ac_try_echo
=
$ac_try
;;
esac
eval
"echo
\"\$
as_me:
$LINENO
:
$ac_try_echo
\"
"
)
>
&5
(
eval
"
$ac_link
"
)
2>&5
ac_status
=
$?
echo
"
$as_me
:
$LINENO
:
\$
? =
$ac_status
"
>
&5
(
exit
$ac_status
)
;
}
&&
{
ac_try
=
'./conftest$ac_exeext'
{
(
case
"((
$ac_try
"
in
*
\"
*
|
*
\`
*
|
*
\\
*
)
ac_try_echo
=
\$
ac_try
;;
*
)
ac_try_echo
=
$ac_try
;;
esac
eval
"echo
\"\$
as_me:
$LINENO
:
$ac_try_echo
\"
"
)
>
&5
(
eval
"
$ac_try
"
)
2>&5
ac_status
=
$?
echo
"
$as_me
:
$LINENO
:
\$
? =
$ac_status
"
>
&5
(
exit
$ac_status
)
;
}
;
}
;
then
ac_cv_have_long_long_format
=
yes
else
echo
"
$as_me
: program exited with status
$ac_status
"
>
&5
echo
"
$as_me
: failed program was:"
>
&5
sed
's/^/| /'
conftest.
$ac_ext
>
&5
(
exit
$ac_status
)
ac_cv_have_long_long_format
=
no
fi
rm
-f
core
*
.core core.conftest.
*
gmon.out bb.out conftest
$ac_exeext
conftest.
$ac_objext
conftest.
$ac_ext
fi
fi
{
echo
"
$as_me
:
$LINENO
: result:
$ac_cv_have_long_long_format
"
>
&5
echo
"
${
ECHO_T
}
$ac_cv_have_long_long_format
"
>
&6
;
}
fi
if
test
$ac_cv_have_long_long_format
=
yes
then
cat
>>
confdefs.h
<<
\
_ACEOF
#define PY_FORMAT_LONG_LONG "ll"
_ACEOF
fi
{
echo
"
$as_me
:
$LINENO
: checking for %zd printf() format support"
>
&5
echo
$ECHO_N
"checking for %zd printf() format support...
$ECHO_C
"
>
&6
;
}
if
test
"
${
ac_cv_have_size_t_format
+set
}
"
=
set
;
then
...
...
configure.in
View file @
82864d1a
...
...
@@ -3952,6 +3952,54 @@ else
AC_MSG_RESULT(no)
fi
if test "$have_long_long" = yes
then
AC_MSG_CHECKING(for %lld and %llu printf() format support)
AC_CACHE_VAL(ac_cv_have_long_long_format,
AC_TRY_RUN([[
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
int main()
{
char buffer[256];
if (sprintf(buffer, "%lld", (long long)123) < 0)
return 1;
if (strcmp(buffer, "123"))
return 1;
if (sprintf(buffer, "%lld", (long long)-123) < 0)
return 1;
if (strcmp(buffer, "-123"))
return 1;
if (sprintf(buffer, "%llu", (unsigned long long)123) < 0)
return 1;
if (strcmp(buffer, "123"))
return 1;
return 0;
}
]], ac_cv_have_long_long_format=yes,
ac_cv_have_long_long_format=no,
ac_cv_have_long_long_format=no)
)
AC_MSG_RESULT($ac_cv_have_long_long_format)
fi
if test $ac_cv_have_long_long_format = yes
then
AC_DEFINE(PY_FORMAT_LONG_LONG, "ll",
[Define to printf format modifier for long long type])
fi
AC_CACHE_CHECK([for %zd printf() format support], ac_cv_have_size_t_format, [dnl
AC_TRY_RUN([
#include <stdio.h>
...
...
pyconfig.h.in
View file @
82864d1a
...
...
@@ -903,6 +903,9 @@
/* Define as the preferred size in bits of long digits */
#undef PYLONG_BITS_IN_DIGIT
/* Define to printf format modifier for long long type */
#undef PY_FORMAT_LONG_LONG
/* Define to printf format modifier for Py_ssize_t */
#undef PY_FORMAT_SIZE_T
...
...
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