[pypy-commit] pypy win32-cleanup2: merge from default
mattip
noreply at buildbot.pypy.org
Wed May 2 17:07:15 CEST 2012
Author: mattip
Branch: win32-cleanup2
Changeset: r54874:f8b3c6c64ce9
Date: 2012-05-02 16:59 +0300
http://bitbucket.org/pypy/pypy/changeset/f8b3c6c64ce9/
Log: merge from default
diff too long, truncating to 10000 out of 12873 lines
diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst
--- a/pypy/doc/cppyy.rst
+++ b/pypy/doc/cppyy.rst
@@ -21,6 +21,26 @@
.. _`llvm`: http://llvm.org/
+Motivation
+==========
+
+The cppyy module offers two unique features, which result in great
+performance as well as better functionality and cross-language integration
+than would otherwise be possible.
+First, cppyy is written in RPython and therefore open to optimizations by the
+JIT up until the actual point of call into C++.
+This means that there are no conversions necessary between a garbage collected
+and a reference counted environment, as is needed for the use of existing
+extension modules written or generated for CPython.
+It also means that if variables are already unboxed by the JIT, they can be
+passed through directly to C++.
+Second, Reflex (and cling far more so) adds dynamic features to C++, thus
+greatly reducing impedance mismatches between the two languages.
+In fact, Reflex is dynamic enough that you could write the runtime bindings
+generation in python (as opposed to RPython) and this is used to create very
+natural "pythonizations" of the bound code.
+
+
Installation
============
@@ -195,10 +215,12 @@
>>>> d = cppyy.gbl.BaseFactory("name", 42, 3.14)
>>>> type(d)
<class '__main__.Derived'>
- >>>> d.m_i
- 42
- >>>> d.m_d
- 3.14
+ >>>> isinstance(d, cppyy.gbl.Base1)
+ True
+ >>>> isinstance(d, cppyy.gbl.Base2)
+ True
+ >>>> d.m_i, d.m_d
+ (42, 3.14)
>>>> d.m_name == "name"
True
>>>>
@@ -295,6 +317,9 @@
To select a specific virtual method, do like with normal python classes
that override methods: select it from the class that you need, rather than
calling the method on the instance.
+ To select a specific overload, use the __dispatch__ special function, which
+ takes the name of the desired method and its signature (which can be
+ obtained from the doc string) as arguments.
* **namespaces**: Are represented as python classes.
Namespaces are more open-ended than classes, so sometimes initial access may
diff --git a/pypy/doc/extending.rst b/pypy/doc/extending.rst
--- a/pypy/doc/extending.rst
+++ b/pypy/doc/extending.rst
@@ -116,13 +116,21 @@
Reflex
======
-This method is only experimental for now, and is being exercised on a branch,
-`reflex-support`_, so you will have to build PyPy yourself.
+This method is still experimental and is being exercised on a branch,
+`reflex-support`_, which adds the `cppyy`_ module.
The method works by using the `Reflex package`_ to provide reflection
information of the C++ code, which is then used to automatically generate
-bindings at runtime, which can then be used from python.
+bindings at runtime.
+From a python standpoint, there is no difference between generating bindings
+at runtime, or having them "statically" generated and available in scripts
+or compiled into extension modules: python classes and functions are always
+runtime structures, created when a script or module loads.
+However, if the backend itself is capable of dynamic behavior, it is a much
+better functional match to python, allowing tighter integration and more
+natural language mappings.
Full details are `available here`_.
+.. _`cppyy`: cppyy.html
.. _`reflex-support`: cppyy.html
.. _`Reflex package`: http://root.cern.ch/drupal/content/reflex
.. _`available here`: cppyy.html
@@ -130,16 +138,33 @@
Pros
----
-If it works, it is mostly automatic, and hence easy in use.
-The bindings can make use of direct pointers, in which case the calls are
-very fast.
+The cppyy module is written in RPython, which makes it possible to keep the
+code execution visible to the JIT all the way to the actual point of call into
+C++, thus allowing for a very fast interface.
+Reflex is currently in use in large software environments in High Energy
+Physics (HEP), across many different projects and packages, and its use can be
+virtually completely automated in a production environment.
+One of its uses in HEP is in providing language bindings for CPython.
+Thus, it is possible to use Reflex to have bound code work on both CPython and
+on PyPy.
+In the medium-term, Reflex will be replaced by `cling`_, which is based on
+`llvm`_.
+This will affect the backend only; the python-side interface is expected to
+remain the same, except that cling adds a lot of dynamic behavior to C++,
+enabling further language integration.
+
+.. _`cling`: http://root.cern.ch/drupal/content/cling
+.. _`llvm`: http://llvm.org/
Cons
----
-C++ is a large language, and these bindings are not yet feature-complete.
-Although missing features should do no harm if you don't use them, if you do
-need a particular feature, it may be necessary to work around it in python
-or with a C++ helper function.
+C++ is a large language, and cppyy is not yet feature-complete.
+Still, the experience gained in developing the equivalent bindings for CPython
+means that adding missing features is a simple matter of engineering, not a
+question of research.
+The module is written so that currently missing features should do no harm if
+you don't use them, if you do need a particular feature, it may be necessary
+to work around it in python or with a C++ helper function.
Although Reflex works on various platforms, the bindings with PyPy have only
been tested on Linux.
diff --git a/pypy/jit/backend/llsupport/test/test_asmmemmgr.py b/pypy/jit/backend/llsupport/test/test_asmmemmgr.py
--- a/pypy/jit/backend/llsupport/test/test_asmmemmgr.py
+++ b/pypy/jit/backend/llsupport/test/test_asmmemmgr.py
@@ -217,7 +217,8 @@
encoded = ''.join(writtencode).encode('hex').upper()
ataddr = '@%x' % addr
assert log == [('test-logname-section',
- [('debug_print', 'CODE_DUMP', ataddr, '+0 ', encoded)])]
+ [('debug_print', 'SYS_EXECUTABLE', '??'),
+ ('debug_print', 'CODE_DUMP', ataddr, '+0 ', encoded)])]
lltype.free(p, flavor='raw')
diff --git a/pypy/jit/metainterp/jitexc.py b/pypy/jit/metainterp/jitexc.py
--- a/pypy/jit/metainterp/jitexc.py
+++ b/pypy/jit/metainterp/jitexc.py
@@ -12,7 +12,6 @@
"""
_go_through_llinterp_uncaught_ = True # ugh
-
def _get_standard_error(rtyper, Class):
exdata = rtyper.getexceptiondata()
clsdef = rtyper.annotator.bookkeeper.getuniqueclassdef(Class)
diff --git a/pypy/jit/metainterp/optimize.py b/pypy/jit/metainterp/optimize.py
--- a/pypy/jit/metainterp/optimize.py
+++ b/pypy/jit/metainterp/optimize.py
@@ -5,3 +5,9 @@
"""Raised when the optimize*.py detect that the loop that
we are trying to build cannot possibly make sense as a
long-running loop (e.g. it cannot run 2 complete iterations)."""
+
+ def __init__(self, msg='?'):
+ debug_start("jit-abort")
+ debug_print(msg)
+ debug_stop("jit-abort")
+ self.msg = msg
diff --git a/pypy/jit/metainterp/optimizeopt/__init__.py b/pypy/jit/metainterp/optimizeopt/__init__.py
--- a/pypy/jit/metainterp/optimizeopt/__init__.py
+++ b/pypy/jit/metainterp/optimizeopt/__init__.py
@@ -49,8 +49,9 @@
optimizations.append(OptFfiCall())
if ('rewrite' not in enable_opts or 'virtualize' not in enable_opts
- or 'heap' not in enable_opts or 'unroll' not in enable_opts):
- optimizations.append(OptSimplify())
+ or 'heap' not in enable_opts or 'unroll' not in enable_opts
+ or 'pure' not in enable_opts):
+ optimizations.append(OptSimplify(unroll))
return optimizations, unroll
diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py
--- a/pypy/jit/metainterp/optimizeopt/heap.py
+++ b/pypy/jit/metainterp/optimizeopt/heap.py
@@ -257,8 +257,8 @@
opnum == rop.COPYSTRCONTENT or # no effect on GC struct/array
opnum == rop.COPYUNICODECONTENT): # no effect on GC struct/array
return
- assert opnum != rop.CALL_PURE
if (opnum == rop.CALL or
+ opnum == rop.CALL_PURE or
opnum == rop.CALL_MAY_FORCE or
opnum == rop.CALL_RELEASE_GIL or
opnum == rop.CALL_ASSEMBLER):
@@ -481,7 +481,7 @@
# already between the tracing and now. In this case, we are
# simply ignoring the QUASIIMMUT_FIELD hint and compiling it
# as a regular getfield.
- if not qmutdescr.is_still_valid():
+ if not qmutdescr.is_still_valid_for(structvalue.get_key_box()):
self._remove_guard_not_invalidated = True
return
# record as an out-of-line guard
diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py
--- a/pypy/jit/metainterp/optimizeopt/intbounds.py
+++ b/pypy/jit/metainterp/optimizeopt/intbounds.py
@@ -191,10 +191,13 @@
# GUARD_OVERFLOW, then the loop is invalid.
lastop = self.last_emitted_operation
if lastop is None:
- raise InvalidLoop
+ raise InvalidLoop('An INT_xxx_OVF was proven not to overflow but' +
+ 'guarded with GUARD_OVERFLOW')
opnum = lastop.getopnum()
if opnum not in (rop.INT_ADD_OVF, rop.INT_SUB_OVF, rop.INT_MUL_OVF):
- raise InvalidLoop
+ raise InvalidLoop('An INT_xxx_OVF was proven not to overflow but' +
+ 'guarded with GUARD_OVERFLOW')
+
self.emit_operation(op)
def optimize_INT_ADD_OVF(self, op):
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -525,6 +525,7 @@
@specialize.argtype(0)
def _emit_operation(self, op):
+ assert op.getopnum() != rop.CALL_PURE
for i in range(op.numargs()):
arg = op.getarg(i)
try:
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -208,7 +208,8 @@
box = value.box
assert isinstance(box, Const)
if not box.same_constant(constbox):
- raise InvalidLoop
+ raise InvalidLoop('A GURAD_{VALUE,TRUE,FALSE} was proven to' +
+ 'always fail')
return
if emit_operation:
self.emit_operation(op)
@@ -220,7 +221,7 @@
if value.is_null():
return
elif value.is_nonnull():
- raise InvalidLoop
+ raise InvalidLoop('A GUARD_ISNULL was proven to always fail')
self.emit_operation(op)
value.make_constant(self.optimizer.cpu.ts.CONST_NULL)
@@ -229,7 +230,7 @@
if value.is_nonnull():
return
elif value.is_null():
- raise InvalidLoop
+ raise InvalidLoop('A GUARD_NONNULL was proven to always fail')
self.emit_operation(op)
value.make_nonnull(op)
@@ -278,7 +279,7 @@
if realclassbox is not None:
if realclassbox.same_constant(expectedclassbox):
return
- raise InvalidLoop
+ raise InvalidLoop('A GUARD_CLASS was proven to always fail')
if value.last_guard:
# there already has been a guard_nonnull or guard_class or
# guard_nonnull_class on this value.
@@ -301,7 +302,8 @@
def optimize_GUARD_NONNULL_CLASS(self, op):
value = self.getvalue(op.getarg(0))
if value.is_null():
- raise InvalidLoop
+ raise InvalidLoop('A GUARD_NONNULL_CLASS was proven to always ' +
+ 'fail')
self.optimize_GUARD_CLASS(op)
def optimize_CALL_LOOPINVARIANT(self, op):
diff --git a/pypy/jit/metainterp/optimizeopt/simplify.py b/pypy/jit/metainterp/optimizeopt/simplify.py
--- a/pypy/jit/metainterp/optimizeopt/simplify.py
+++ b/pypy/jit/metainterp/optimizeopt/simplify.py
@@ -4,8 +4,9 @@
from pypy.jit.metainterp.history import TargetToken, JitCellToken
class OptSimplify(Optimization):
- def __init__(self):
+ def __init__(self, unroll):
self.last_label_descr = None
+ self.unroll = unroll
def optimize_CALL_PURE(self, op):
args = op.getarglist()
@@ -35,24 +36,26 @@
pass
def optimize_LABEL(self, op):
- descr = op.getdescr()
- if isinstance(descr, JitCellToken):
- return self.optimize_JUMP(op.copy_and_change(rop.JUMP))
- self.last_label_descr = op.getdescr()
+ if not self.unroll:
+ descr = op.getdescr()
+ if isinstance(descr, JitCellToken):
+ return self.optimize_JUMP(op.copy_and_change(rop.JUMP))
+ self.last_label_descr = op.getdescr()
self.emit_operation(op)
def optimize_JUMP(self, op):
- descr = op.getdescr()
- assert isinstance(descr, JitCellToken)
- if not descr.target_tokens:
- assert self.last_label_descr is not None
- target_token = self.last_label_descr
- assert isinstance(target_token, TargetToken)
- assert target_token.targeting_jitcell_token is descr
- op.setdescr(self.last_label_descr)
- else:
- assert len(descr.target_tokens) == 1
- op.setdescr(descr.target_tokens[0])
+ if not self.unroll:
+ descr = op.getdescr()
+ assert isinstance(descr, JitCellToken)
+ if not descr.target_tokens:
+ assert self.last_label_descr is not None
+ target_token = self.last_label_descr
+ assert isinstance(target_token, TargetToken)
+ assert target_token.targeting_jitcell_token is descr
+ op.setdescr(self.last_label_descr)
+ else:
+ assert len(descr.target_tokens) == 1
+ op.setdescr(descr.target_tokens[0])
self.emit_operation(op)
dispatch_opt = make_dispatcher_method(OptSimplify, 'optimize_',
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_disable_optimizations.py b/pypy/jit/metainterp/optimizeopt/test/test_disable_optimizations.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/metainterp/optimizeopt/test/test_disable_optimizations.py
@@ -0,0 +1,46 @@
+from pypy.jit.metainterp.optimizeopt.test.test_optimizeopt import OptimizeOptTest
+from pypy.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin
+from pypy.jit.metainterp.resoperation import rop
+
+
+allopts = OptimizeOptTest.enable_opts.split(':')
+for optnum in range(len(allopts)):
+ myopts = allopts[:]
+ del myopts[optnum]
+
+ class TestLLtype(OptimizeOptTest, LLtypeMixin):
+ enable_opts = ':'.join(myopts)
+
+ def optimize_loop(self, ops, expected, expected_preamble=None,
+ call_pure_results=None, expected_short=None):
+ loop = self.parse(ops)
+ if expected != "crash!":
+ expected = self.parse(expected)
+ if expected_preamble:
+ expected_preamble = self.parse(expected_preamble)
+ if expected_short:
+ expected_short = self.parse(expected_short)
+
+ preamble = self.unroll_and_optimize(loop, call_pure_results)
+
+ for op in preamble.operations + loop.operations:
+ assert op.getopnum() not in (rop.CALL_PURE,
+ rop.CALL_LOOPINVARIANT,
+ rop.VIRTUAL_REF_FINISH,
+ rop.VIRTUAL_REF,
+ rop.QUASIIMMUT_FIELD,
+ rop.MARK_OPAQUE_PTR,
+ rop.RECORD_KNOWN_CLASS)
+
+ def raises(self, e, fn, *args):
+ try:
+ fn(*args)
+ except e:
+ pass
+
+ opt = allopts[optnum]
+ exec "TestNo%sLLtype = TestLLtype" % (opt[0].upper() + opt[1:])
+
+del TestLLtype # No need to run the last set twice
+del TestNoUnrollLLtype # This case is take care of by test_optimizebasic
+
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -5090,7 +5090,6 @@
class TestLLtype(BaseTestOptimizeBasic, LLtypeMixin):
pass
-
##class TestOOtype(BaseTestOptimizeBasic, OOtypeMixin):
## def test_instanceof(self):
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -105,6 +105,9 @@
return loop
+ def raises(self, e, fn, *args):
+ py.test.raises(e, fn, *args)
+
class OptimizeOptTest(BaseTestWithUnroll):
def setup_method(self, meth=None):
@@ -2639,7 +2642,7 @@
p2 = new_with_vtable(ConstClass(node_vtable))
jump(p2)
"""
- py.test.raises(InvalidLoop, self.optimize_loop,
+ self.raises(InvalidLoop, self.optimize_loop,
ops, ops)
def test_invalid_loop_2(self):
@@ -2651,7 +2654,7 @@
escape(p2) # prevent it from staying Virtual
jump(p2)
"""
- py.test.raises(InvalidLoop, self.optimize_loop,
+ self.raises(InvalidLoop, self.optimize_loop,
ops, ops)
def test_invalid_loop_3(self):
@@ -2665,7 +2668,7 @@
setfield_gc(p3, p4, descr=nextdescr)
jump(p3)
"""
- py.test.raises(InvalidLoop, self.optimize_loop, ops, ops)
+ self.raises(InvalidLoop, self.optimize_loop, ops, ops)
def test_merge_guard_class_guard_value(self):
@@ -4411,7 +4414,7 @@
setfield_gc(p1, p3, descr=nextdescr)
jump(p3)
"""
- py.test.raises(BogusPureField, self.optimize_loop, ops, "crash!")
+ self.raises(BogusPureField, self.optimize_loop, ops, "crash!")
def test_dont_complains_different_field(self):
ops = """
@@ -5024,7 +5027,7 @@
i2 = int_add(i0, 3)
jump(i2)
"""
- py.test.raises(InvalidLoop, self.optimize_loop, ops, ops)
+ self.raises(InvalidLoop, self.optimize_loop, ops, ops)
def test_bound_ne_const_not(self):
ops = """
@@ -5074,7 +5077,7 @@
i3 = int_add(i0, 3)
jump(i3)
"""
- py.test.raises(InvalidLoop, self.optimize_loop, ops, ops)
+ self.raises(InvalidLoop, self.optimize_loop, ops, ops)
def test_bound_lshift(self):
ops = """
@@ -6533,9 +6536,9 @@
def test_quasi_immut_2(self):
ops = """
[]
- quasiimmut_field(ConstPtr(myptr), descr=quasiimmutdescr)
+ quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr)
guard_not_invalidated() []
- i1 = getfield_gc(ConstPtr(myptr), descr=quasifielddescr)
+ i1 = getfield_gc(ConstPtr(quasiptr), descr=quasifielddescr)
escape(i1)
jump()
"""
@@ -6585,13 +6588,13 @@
def test_call_may_force_invalidated_guards_reload(self):
ops = """
[i0a, i0b]
- quasiimmut_field(ConstPtr(myptr), descr=quasiimmutdescr)
+ quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr)
guard_not_invalidated() []
- i1 = getfield_gc(ConstPtr(myptr), descr=quasifielddescr)
+ i1 = getfield_gc(ConstPtr(quasiptr), descr=quasifielddescr)
call_may_force(i0b, descr=mayforcevirtdescr)
- quasiimmut_field(ConstPtr(myptr), descr=quasiimmutdescr)
+ quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr)
guard_not_invalidated() []
- i2 = getfield_gc(ConstPtr(myptr), descr=quasifielddescr)
+ i2 = getfield_gc(ConstPtr(quasiptr), descr=quasifielddescr)
i3 = escape(i1)
i4 = escape(i2)
jump(i3, i4)
@@ -7813,6 +7816,52 @@
"""
self.optimize_loop(ops, expected)
+ def test_issue1080_infinitie_loop_virtual(self):
+ ops = """
+ [p10]
+ p52 = getfield_gc(p10, descr=nextdescr) # inst_storage
+ p54 = getarrayitem_gc(p52, 0, descr=arraydescr)
+ p69 = getfield_gc_pure(p54, descr=otherdescr) # inst_w_function
+
+ quasiimmut_field(p69, descr=quasiimmutdescr)
+ guard_not_invalidated() []
+ p71 = getfield_gc(p69, descr=quasifielddescr) # inst_code
+ guard_value(p71, -4247) []
+
+ p106 = new_with_vtable(ConstClass(node_vtable))
+ p108 = new_array(3, descr=arraydescr)
+ p110 = new_with_vtable(ConstClass(node_vtable))
+ setfield_gc(p110, ConstPtr(myptr2), descr=otherdescr) # inst_w_function
+ setarrayitem_gc(p108, 0, p110, descr=arraydescr)
+ setfield_gc(p106, p108, descr=nextdescr) # inst_storage
+ jump(p106)
+ """
+ expected = """
+ []
+ p72 = getfield_gc(ConstPtr(myptr2), descr=quasifielddescr)
+ guard_value(p72, -4247) []
+ jump()
+ """
+ self.optimize_loop(ops, expected)
+
+
+ def test_issue1080_infinitie_loop_simple(self):
+ ops = """
+ [p69]
+ quasiimmut_field(p69, descr=quasiimmutdescr)
+ guard_not_invalidated() []
+ p71 = getfield_gc(p69, descr=quasifielddescr) # inst_code
+ guard_value(p71, -4247) []
+ jump(ConstPtr(myptr))
+ """
+ expected = """
+ []
+ p72 = getfield_gc(ConstPtr(myptr), descr=quasifielddescr)
+ guard_value(p72, -4247) []
+ jump()
+ """
+ self.optimize_loop(ops, expected)
+
class TestLLtype(OptimizeOptTest, LLtypeMixin):
pass
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py b/pypy/jit/metainterp/optimizeopt/test/test_util.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_util.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py
@@ -122,6 +122,7 @@
quasi.inst_field = -4247
quasifielddescr = cpu.fielddescrof(QUASI, 'inst_field')
quasibox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, quasi))
+ quasiptr = quasibox.value
quasiimmutdescr = QuasiImmutDescr(cpu, quasibox,
quasifielddescr,
cpu.fielddescrof(QUASI, 'mutate_field'))
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -315,7 +315,10 @@
try:
jumpargs = virtual_state.make_inputargs(values, self.optimizer)
except BadVirtualState:
- raise InvalidLoop
+ raise InvalidLoop('The state of the optimizer at the end of ' +
+ 'peeled loop is inconsistent with the ' +
+ 'VirtualState at the begining of the peeled ' +
+ 'loop')
jumpop.initarglist(jumpargs)
# Inline the short preamble at the end of the loop
@@ -325,7 +328,11 @@
for i in range(len(short_inputargs)):
if short_inputargs[i] in args:
if args[short_inputargs[i]] != jmp_to_short_args[i]:
- raise InvalidLoop
+ raise InvalidLoop('The short preamble wants the ' +
+ 'same box passed to multiple of its ' +
+ 'inputargs, but the jump at the ' +
+ 'end of this bridge does not do that.')
+
args[short_inputargs[i]] = jmp_to_short_args[i]
self.short_inliner = Inliner(short_inputargs, jmp_to_short_args)
for op in self.short[1:]:
@@ -378,7 +385,10 @@
#final_virtual_state.debug_print("Bad virtual state at end of loop, ",
# bad)
#debug_stop('jit-log-virtualstate')
- raise InvalidLoop
+ raise InvalidLoop('The virtual state at the end of the peeled ' +
+ 'loop is not compatible with the virtual ' +
+ 'state at the start of the loop which makes ' +
+ 'it impossible to close the loop')
#debug_stop('jit-log-virtualstate')
@@ -526,8 +536,8 @@
args = jumpop.getarglist()
modifier = VirtualStateAdder(self.optimizer)
virtual_state = modifier.get_virtual_state(args)
- #debug_start('jit-log-virtualstate')
- #virtual_state.debug_print("Looking for ")
+ debug_start('jit-log-virtualstate')
+ virtual_state.debug_print("Looking for ")
for target in cell_token.target_tokens:
if not target.virtual_state:
@@ -536,10 +546,10 @@
extra_guards = []
bad = {}
- #debugmsg = 'Did not match '
+ debugmsg = 'Did not match '
if target.virtual_state.generalization_of(virtual_state, bad):
ok = True
- #debugmsg = 'Matched '
+ debugmsg = 'Matched '
else:
try:
cpu = self.optimizer.cpu
@@ -548,13 +558,13 @@
extra_guards)
ok = True
- #debugmsg = 'Guarded to match '
+ debugmsg = 'Guarded to match '
except InvalidLoop:
pass
- #target.virtual_state.debug_print(debugmsg, bad)
+ target.virtual_state.debug_print(debugmsg, bad)
if ok:
- #debug_stop('jit-log-virtualstate')
+ debug_stop('jit-log-virtualstate')
values = [self.getvalue(arg)
for arg in jumpop.getarglist()]
@@ -581,7 +591,7 @@
jumpop.setdescr(cell_token.target_tokens[0])
self.optimizer.send_extra_operation(jumpop)
return True
- #debug_stop('jit-log-virtualstate')
+ debug_stop('jit-log-virtualstate')
return False
class ValueImporter(object):
diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py b/pypy/jit/metainterp/optimizeopt/virtualstate.py
--- a/pypy/jit/metainterp/optimizeopt/virtualstate.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py
@@ -27,11 +27,15 @@
if self.generalization_of(other, renum, {}):
return
if renum[self.position] != other.position:
- raise InvalidLoop
+ raise InvalidLoop('The numbering of the virtual states does not ' +
+ 'match. This means that two virtual fields ' +
+ 'have been set to the same Box in one of the ' +
+ 'virtual states but not in the other.')
self._generate_guards(other, box, cpu, extra_guards)
def _generate_guards(self, other, box, cpu, extra_guards):
- raise InvalidLoop
+ raise InvalidLoop('Generating guards for making the VirtualStates ' +
+ 'at hand match have not been implemented')
def enum_forced_boxes(self, boxes, value, optimizer):
raise NotImplementedError
@@ -346,10 +350,12 @@
def _generate_guards(self, other, box, cpu, extra_guards):
if not isinstance(other, NotVirtualStateInfo):
- raise InvalidLoop
+ raise InvalidLoop('The VirtualStates does not match as a ' +
+ 'virtual appears where a pointer is needed ' +
+ 'and it is too late to force it.')
if self.lenbound or other.lenbound:
- raise InvalidLoop
+ raise InvalidLoop('The array length bounds does not match.')
if self.level == LEVEL_KNOWNCLASS and \
box.nonnull() and \
@@ -400,7 +406,8 @@
return
# Remaining cases are probably not interesting
- raise InvalidLoop
+ raise InvalidLoop('Generating guards for making the VirtualStates ' +
+ 'at hand match have not been implemented')
if self.level == LEVEL_CONSTANT:
import pdb; pdb.set_trace()
raise NotImplementedError
diff --git a/pypy/jit/metainterp/quasiimmut.py b/pypy/jit/metainterp/quasiimmut.py
--- a/pypy/jit/metainterp/quasiimmut.py
+++ b/pypy/jit/metainterp/quasiimmut.py
@@ -120,8 +120,10 @@
self.fielddescr, self.structbox)
return fieldbox.constbox()
- def is_still_valid(self):
+ def is_still_valid_for(self, structconst):
assert self.structbox is not None
+ if not self.structbox.constbox().same_constant(structconst):
+ return False
cpu = self.cpu
gcref = self.structbox.getref_base()
qmut = get_current_qmut_instance(cpu, gcref, self.mutatefielddescr)
diff --git a/pypy/jit/metainterp/test/test_quasiimmut.py b/pypy/jit/metainterp/test/test_quasiimmut.py
--- a/pypy/jit/metainterp/test/test_quasiimmut.py
+++ b/pypy/jit/metainterp/test/test_quasiimmut.py
@@ -8,7 +8,7 @@
from pypy.jit.metainterp.quasiimmut import get_current_qmut_instance
from pypy.jit.metainterp.test.support import LLJitMixin
from pypy.jit.codewriter.policy import StopAtXPolicy
-from pypy.rlib.jit import JitDriver, dont_look_inside, unroll_safe
+from pypy.rlib.jit import JitDriver, dont_look_inside, unroll_safe, promote
def test_get_current_qmut_instance():
@@ -506,6 +506,27 @@
"guard_not_invalidated": 2
})
+ def test_issue1080(self):
+ myjitdriver = JitDriver(greens=[], reds=["n", "sa", "a"])
+ class Foo(object):
+ _immutable_fields_ = ["x?"]
+ def __init__(self, x):
+ self.x = x
+ one, two = Foo(1), Foo(2)
+ def main(n):
+ sa = 0
+ a = one
+ while n:
+ myjitdriver.jit_merge_point(n=n, sa=sa, a=a)
+ sa += a.x
+ if a.x == 1:
+ a = two
+ elif a.x == 2:
+ a = one
+ n -= 1
+ return sa
+ res = self.meta_interp(main, [10])
+ assert res == main(10)
class TestLLtypeGreenFieldsTests(QuasiImmutTests, LLJitMixin):
pass
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -936,12 +936,12 @@
source_dir / "pyerrors.c",
source_dir / "modsupport.c",
source_dir / "getargs.c",
+ source_dir / "abstract.c",
source_dir / "stringobject.c",
source_dir / "mysnprintf.c",
source_dir / "pythonrun.c",
source_dir / "sysmodule.c",
source_dir / "bufferobject.c",
- source_dir / "object.c",
source_dir / "cobject.c",
source_dir / "structseq.c",
source_dir / "capsule.c",
diff --git a/pypy/module/cpyext/complexobject.py b/pypy/module/cpyext/complexobject.py
--- a/pypy/module/cpyext/complexobject.py
+++ b/pypy/module/cpyext/complexobject.py
@@ -33,6 +33,11 @@
# CPython also accepts anything
return 0.0
+ at cpython_api([Py_complex_ptr], PyObject)
+def _PyComplex_FromCComplex(space, v):
+ """Create a new Python complex number object from a C Py_complex value."""
+ return space.newcomplex(v.c_real, v.c_imag)
+
# lltype does not handle functions returning a structure. This implements a
# helper function, which takes as argument a reference to the return value.
@cpython_api([PyObject, Py_complex_ptr], lltype.Void)
diff --git a/pypy/module/cpyext/floatobject.py b/pypy/module/cpyext/floatobject.py
--- a/pypy/module/cpyext/floatobject.py
+++ b/pypy/module/cpyext/floatobject.py
@@ -2,6 +2,7 @@
from pypy.module.cpyext.api import (
CANNOT_FAIL, cpython_api, PyObject, build_type_checkers, CONST_STRING)
from pypy.interpreter.error import OperationError
+from pypy.rlib.rstruct import runpack
PyFloat_Check, PyFloat_CheckExact = build_type_checkers("Float")
@@ -33,3 +34,19 @@
backward compatibility."""
return space.call_function(space.w_float, w_obj)
+ at cpython_api([CONST_STRING, rffi.INT_real], rffi.DOUBLE, error=-1.0)
+def _PyFloat_Unpack4(space, ptr, le):
+ input = rffi.charpsize2str(ptr, 4)
+ if rffi.cast(lltype.Signed, le):
+ return runpack.runpack("<f", input)
+ else:
+ return runpack.runpack(">f", input)
+
+ at cpython_api([CONST_STRING, rffi.INT_real], rffi.DOUBLE, error=-1.0)
+def _PyFloat_Unpack8(space, ptr, le):
+ input = rffi.charpsize2str(ptr, 8)
+ if rffi.cast(lltype.Signed, le):
+ return runpack.runpack("<d", input)
+ else:
+ return runpack.runpack(">d", input)
+
diff --git a/pypy/module/cpyext/include/complexobject.h b/pypy/module/cpyext/include/complexobject.h
--- a/pypy/module/cpyext/include/complexobject.h
+++ b/pypy/module/cpyext/include/complexobject.h
@@ -21,6 +21,8 @@
return result;
}
+#define PyComplex_FromCComplex(c) _PyComplex_FromCComplex(&c)
+
#ifdef __cplusplus
}
#endif
diff --git a/pypy/module/cpyext/include/pyerrors.h b/pypy/module/cpyext/include/pyerrors.h
--- a/pypy/module/cpyext/include/pyerrors.h
+++ b/pypy/module/cpyext/include/pyerrors.h
@@ -29,6 +29,10 @@
# define vsnprintf _vsnprintf
#endif
+#include <stdarg.h>
+PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...);
+PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va);
+
#ifdef __cplusplus
}
#endif
diff --git a/pypy/module/cpyext/include/stringobject.h b/pypy/module/cpyext/include/stringobject.h
--- a/pypy/module/cpyext/include/stringobject.h
+++ b/pypy/module/cpyext/include/stringobject.h
@@ -7,8 +7,6 @@
extern "C" {
#endif
-int PyOS_snprintf(char *str, size_t size, const char *format, ...);
-
#define PyString_GET_SIZE(op) PyString_Size(op)
#define PyString_AS_STRING(op) PyString_AsString(op)
diff --git a/pypy/module/cpyext/include/structmember.h b/pypy/module/cpyext/include/structmember.h
--- a/pypy/module/cpyext/include/structmember.h
+++ b/pypy/module/cpyext/include/structmember.h
@@ -40,7 +40,8 @@
when the value is NULL, instead of
converting to None. */
#define T_LONGLONG 17
-#define T_ULONGLONG 18
+#define T_ULONGLONG 18
+#define T_PYSSIZET 19
/* Flags. These constants are also in structmemberdefs.py. */
#define READONLY 1
diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py
--- a/pypy/module/cpyext/longobject.py
+++ b/pypy/module/cpyext/longobject.py
@@ -1,6 +1,7 @@
from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.module.cpyext.api import (cpython_api, PyObject, build_type_checkers,
- CONST_STRING, ADDR, CANNOT_FAIL)
+from pypy.module.cpyext.api import (
+ cpython_api, PyObject, build_type_checkers, Py_ssize_t,
+ CONST_STRING, ADDR, CANNOT_FAIL)
from pypy.objspace.std.longobject import W_LongObject
from pypy.interpreter.error import OperationError
from pypy.module.cpyext.intobject import PyInt_AsUnsignedLongMask
@@ -15,6 +16,13 @@
"""Return a new PyLongObject object from v, or NULL on failure."""
return space.newlong(val)
+ at cpython_api([Py_ssize_t], PyObject)
+def PyLong_FromSsize_t(space, val):
+ """Return a new PyLongObject object from a C Py_ssize_t, or
+ NULL on failure.
+ """
+ return space.newlong(val)
+
@cpython_api([rffi.LONGLONG], PyObject)
def PyLong_FromLongLong(space, val):
"""Return a new PyLongObject object from a C long long, or NULL
@@ -56,6 +64,14 @@
and -1 will be returned."""
return space.int_w(w_long)
+ at cpython_api([PyObject], Py_ssize_t, error=-1)
+def PyLong_AsSsize_t(space, w_long):
+ """Return a C Py_ssize_t representation of the contents of pylong. If
+ pylong is greater than PY_SSIZE_T_MAX, an OverflowError is raised
+ and -1 will be returned.
+ """
+ return space.int_w(w_long)
+
@cpython_api([PyObject], rffi.LONGLONG, error=-1)
def PyLong_AsLongLong(space, w_long):
"""
diff --git a/pypy/module/cpyext/src/abstract.c b/pypy/module/cpyext/src/abstract.c
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/src/abstract.c
@@ -0,0 +1,269 @@
+/* Abstract Object Interface */
+
+#include "Python.h"
+
+/* Shorthands to return certain errors */
+
+static PyObject *
+type_error(const char *msg, PyObject *obj)
+{
+ PyErr_Format(PyExc_TypeError, msg, obj->ob_type->tp_name);
+ return NULL;
+}
+
+static PyObject *
+null_error(void)
+{
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_SystemError,
+ "null argument to internal routine");
+ return NULL;
+}
+
+/* Operations on any object */
+
+int
+PyObject_CheckReadBuffer(PyObject *obj)
+{
+ PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
+
+ if (pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL ||
+ (*pb->bf_getsegcount)(obj, NULL) != 1)
+ return 0;
+ return 1;
+}
+
+int PyObject_AsReadBuffer(PyObject *obj,
+ const void **buffer,
+ Py_ssize_t *buffer_len)
+{
+ PyBufferProcs *pb;
+ void *pp;
+ Py_ssize_t len;
+
+ if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+ null_error();
+ return -1;
+ }
+ pb = obj->ob_type->tp_as_buffer;
+ if (pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a readable buffer object");
+ return -1;
+ }
+ if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a single-segment buffer object");
+ return -1;
+ }
+ len = (*pb->bf_getreadbuffer)(obj, 0, &pp);
+ if (len < 0)
+ return -1;
+ *buffer = pp;
+ *buffer_len = len;
+ return 0;
+}
+
+int PyObject_AsWriteBuffer(PyObject *obj,
+ void **buffer,
+ Py_ssize_t *buffer_len)
+{
+ PyBufferProcs *pb;
+ void*pp;
+ Py_ssize_t len;
+
+ if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+ null_error();
+ return -1;
+ }
+ pb = obj->ob_type->tp_as_buffer;
+ if (pb == NULL ||
+ pb->bf_getwritebuffer == NULL ||
+ pb->bf_getsegcount == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a writeable buffer object");
+ return -1;
+ }
+ if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a single-segment buffer object");
+ return -1;
+ }
+ len = (*pb->bf_getwritebuffer)(obj,0,&pp);
+ if (len < 0)
+ return -1;
+ *buffer = pp;
+ *buffer_len = len;
+ return 0;
+}
+
+/* Operations on callable objects */
+
+static PyObject*
+call_function_tail(PyObject *callable, PyObject *args)
+{
+ PyObject *retval;
+
+ if (args == NULL)
+ return NULL;
+
+ if (!PyTuple_Check(args)) {
+ PyObject *a;
+
+ a = PyTuple_New(1);
+ if (a == NULL) {
+ Py_DECREF(args);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(a, 0, args);
+ args = a;
+ }
+ retval = PyObject_Call(callable, args, NULL);
+
+ Py_DECREF(args);
+
+ return retval;
+}
+
+PyObject *
+PyObject_CallFunction(PyObject *callable, const char *format, ...)
+{
+ va_list va;
+ PyObject *args;
+
+ if (callable == NULL)
+ return null_error();
+
+ if (format && *format) {
+ va_start(va, format);
+ args = Py_VaBuildValue(format, va);
+ va_end(va);
+ }
+ else
+ args = PyTuple_New(0);
+
+ return call_function_tail(callable, args);
+}
+
+PyObject *
+PyObject_CallMethod(PyObject *o, const char *name, const char *format, ...)
+{
+ va_list va;
+ PyObject *args;
+ PyObject *func = NULL;
+ PyObject *retval = NULL;
+
+ if (o == NULL || name == NULL)
+ return null_error();
+
+ func = PyObject_GetAttrString(o, name);
+ if (func == NULL) {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return 0;
+ }
+
+ if (!PyCallable_Check(func)) {
+ type_error("attribute of type '%.200s' is not callable", func);
+ goto exit;
+ }
+
+ if (format && *format) {
+ va_start(va, format);
+ args = Py_VaBuildValue(format, va);
+ va_end(va);
+ }
+ else
+ args = PyTuple_New(0);
+
+ retval = call_function_tail(func, args);
+
+ exit:
+ /* args gets consumed in call_function_tail */
+ Py_XDECREF(func);
+
+ return retval;
+}
+
+static PyObject *
+objargs_mktuple(va_list va)
+{
+ int i, n = 0;
+ va_list countva;
+ PyObject *result, *tmp;
+
+#ifdef VA_LIST_IS_ARRAY
+ memcpy(countva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+ __va_copy(countva, va);
+#else
+ countva = va;
+#endif
+#endif
+
+ while (((PyObject *)va_arg(countva, PyObject *)) != NULL)
+ ++n;
+ result = PyTuple_New(n);
+ if (result != NULL && n > 0) {
+ for (i = 0; i < n; ++i) {
+ tmp = (PyObject *)va_arg(va, PyObject *);
+ Py_INCREF(tmp);
+ PyTuple_SET_ITEM(result, i, tmp);
+ }
+ }
+ return result;
+}
+
+PyObject *
+PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
+{
+ PyObject *args, *tmp;
+ va_list vargs;
+
+ if (callable == NULL || name == NULL)
+ return null_error();
+
+ callable = PyObject_GetAttr(callable, name);
+ if (callable == NULL)
+ return NULL;
+
+ /* count the args */
+ va_start(vargs, name);
+ args = objargs_mktuple(vargs);
+ va_end(vargs);
+ if (args == NULL) {
+ Py_DECREF(callable);
+ return NULL;
+ }
+ tmp = PyObject_Call(callable, args, NULL);
+ Py_DECREF(args);
+ Py_DECREF(callable);
+
+ return tmp;
+}
+
+PyObject *
+PyObject_CallFunctionObjArgs(PyObject *callable, ...)
+{
+ PyObject *args, *tmp;
+ va_list vargs;
+
+ if (callable == NULL)
+ return null_error();
+
+ /* count the args */
+ va_start(vargs, callable);
+ args = objargs_mktuple(vargs);
+ va_end(vargs);
+ if (args == NULL)
+ return NULL;
+ tmp = PyObject_Call(callable, args, NULL);
+ Py_DECREF(args);
+
+ return tmp;
+}
+
diff --git a/pypy/module/cpyext/src/bufferobject.c b/pypy/module/cpyext/src/bufferobject.c
--- a/pypy/module/cpyext/src/bufferobject.c
+++ b/pypy/module/cpyext/src/bufferobject.c
@@ -13,207 +13,207 @@
static int
get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
- enum buffer_t buffer_type)
+ enum buffer_t buffer_type)
{
- if (self->b_base == NULL) {
- assert (ptr != NULL);
- *ptr = self->b_ptr;
- *size = self->b_size;
- }
- else {
- Py_ssize_t count, offset;
- readbufferproc proc = 0;
- PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
- if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
- PyErr_SetString(PyExc_TypeError,
- "single-segment buffer object expected");
- return 0;
- }
- if ((buffer_type == READ_BUFFER) ||
- ((buffer_type == ANY_BUFFER) && self->b_readonly))
- proc = bp->bf_getreadbuffer;
- else if ((buffer_type == WRITE_BUFFER) ||
- (buffer_type == ANY_BUFFER))
- proc = (readbufferproc)bp->bf_getwritebuffer;
- else if (buffer_type == CHAR_BUFFER) {
+ if (self->b_base == NULL) {
+ assert (ptr != NULL);
+ *ptr = self->b_ptr;
+ *size = self->b_size;
+ }
+ else {
+ Py_ssize_t count, offset;
+ readbufferproc proc = 0;
+ PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
+ if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return 0;
+ }
+ if ((buffer_type == READ_BUFFER) ||
+ ((buffer_type == ANY_BUFFER) && self->b_readonly))
+ proc = bp->bf_getreadbuffer;
+ else if ((buffer_type == WRITE_BUFFER) ||
+ (buffer_type == ANY_BUFFER))
+ proc = (readbufferproc)bp->bf_getwritebuffer;
+ else if (buffer_type == CHAR_BUFFER) {
if (!PyType_HasFeature(self->ob_type,
- Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
- PyErr_SetString(PyExc_TypeError,
- "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
- return 0;
- }
- proc = (readbufferproc)bp->bf_getcharbuffer;
- }
- if (!proc) {
- char *buffer_type_name;
- switch (buffer_type) {
- case READ_BUFFER:
- buffer_type_name = "read";
- break;
- case WRITE_BUFFER:
- buffer_type_name = "write";
- break;
- case CHAR_BUFFER:
- buffer_type_name = "char";
- break;
- default:
- buffer_type_name = "no";
- break;
- }
- PyErr_Format(PyExc_TypeError,
- "%s buffer type not available",
- buffer_type_name);
- return 0;
- }
- if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
- return 0;
- /* apply constraints to the start/end */
- if (self->b_offset > count)
- offset = count;
- else
- offset = self->b_offset;
- *(char **)ptr = *(char **)ptr + offset;
- if (self->b_size == Py_END_OF_BUFFER)
- *size = count;
- else
- *size = self->b_size;
- if (offset + *size > count)
- *size = count - offset;
- }
- return 1;
+ Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
+ return 0;
+ }
+ proc = (readbufferproc)bp->bf_getcharbuffer;
+ }
+ if (!proc) {
+ char *buffer_type_name;
+ switch (buffer_type) {
+ case READ_BUFFER:
+ buffer_type_name = "read";
+ break;
+ case WRITE_BUFFER:
+ buffer_type_name = "write";
+ break;
+ case CHAR_BUFFER:
+ buffer_type_name = "char";
+ break;
+ default:
+ buffer_type_name = "no";
+ break;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%s buffer type not available",
+ buffer_type_name);
+ return 0;
+ }
+ if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
+ return 0;
+ /* apply constraints to the start/end */
+ if (self->b_offset > count)
+ offset = count;
+ else
+ offset = self->b_offset;
+ *(char **)ptr = *(char **)ptr + offset;
+ if (self->b_size == Py_END_OF_BUFFER)
+ *size = count;
+ else
+ *size = self->b_size;
+ if (offset + *size > count)
+ *size = count - offset;
+ }
+ return 1;
}
static PyObject *
buffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr,
- int readonly)
+ int readonly)
{
- PyBufferObject * b;
+ PyBufferObject * b;
- if (size < 0 && size != Py_END_OF_BUFFER) {
- PyErr_SetString(PyExc_ValueError,
- "size must be zero or positive");
- return NULL;
- }
- if (offset < 0) {
- PyErr_SetString(PyExc_ValueError,
- "offset must be zero or positive");
- return NULL;
- }
+ if (size < 0 && size != Py_END_OF_BUFFER) {
+ PyErr_SetString(PyExc_ValueError,
+ "size must be zero or positive");
+ return NULL;
+ }
+ if (offset < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "offset must be zero or positive");
+ return NULL;
+ }
- b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
- if ( b == NULL )
- return NULL;
+ b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
+ if ( b == NULL )
+ return NULL;
- Py_XINCREF(base);
- b->b_base = base;
- b->b_ptr = ptr;
- b->b_size = size;
- b->b_offset = offset;
- b->b_readonly = readonly;
- b->b_hash = -1;
+ Py_XINCREF(base);
+ b->b_base = base;
+ b->b_ptr = ptr;
+ b->b_size = size;
+ b->b_offset = offset;
+ b->b_readonly = readonly;
+ b->b_hash = -1;
- return (PyObject *) b;
+ return (PyObject *) b;
}
static PyObject *
buffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly)
{
- if (offset < 0) {
- PyErr_SetString(PyExc_ValueError,
- "offset must be zero or positive");
- return NULL;
- }
- if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
- /* another buffer, refer to the base object */
- PyBufferObject *b = (PyBufferObject *)base;
- if (b->b_size != Py_END_OF_BUFFER) {
- Py_ssize_t base_size = b->b_size - offset;
- if (base_size < 0)
- base_size = 0;
- if (size == Py_END_OF_BUFFER || size > base_size)
- size = base_size;
- }
- offset += b->b_offset;
- base = b->b_base;
- }
- return buffer_from_memory(base, size, offset, NULL, readonly);
+ if (offset < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "offset must be zero or positive");
+ return NULL;
+ }
+ if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
+ /* another buffer, refer to the base object */
+ PyBufferObject *b = (PyBufferObject *)base;
+ if (b->b_size != Py_END_OF_BUFFER) {
+ Py_ssize_t base_size = b->b_size - offset;
+ if (base_size < 0)
+ base_size = 0;
+ if (size == Py_END_OF_BUFFER || size > base_size)
+ size = base_size;
+ }
+ offset += b->b_offset;
+ base = b->b_base;
+ }
+ return buffer_from_memory(base, size, offset, NULL, readonly);
}
PyObject *
PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
{
- PyBufferProcs *pb = base->ob_type->tp_as_buffer;
+ PyBufferProcs *pb = base->ob_type->tp_as_buffer;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_SetString(PyExc_TypeError, "buffer object expected");
- return NULL;
- }
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_SetString(PyExc_TypeError, "buffer object expected");
+ return NULL;
+ }
- return buffer_from_object(base, size, offset, 1);
+ return buffer_from_object(base, size, offset, 1);
}
PyObject *
PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
{
- PyBufferProcs *pb = base->ob_type->tp_as_buffer;
+ PyBufferProcs *pb = base->ob_type->tp_as_buffer;
- if ( pb == NULL ||
- pb->bf_getwritebuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_SetString(PyExc_TypeError, "buffer object expected");
- return NULL;
- }
+ if ( pb == NULL ||
+ pb->bf_getwritebuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_SetString(PyExc_TypeError, "buffer object expected");
+ return NULL;
+ }
- return buffer_from_object(base, size, offset, 0);
+ return buffer_from_object(base, size, offset, 0);
}
PyObject *
PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
{
- return buffer_from_memory(NULL, size, 0, ptr, 1);
+ return buffer_from_memory(NULL, size, 0, ptr, 1);
}
PyObject *
PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
{
- return buffer_from_memory(NULL, size, 0, ptr, 0);
+ return buffer_from_memory(NULL, size, 0, ptr, 0);
}
PyObject *
PyBuffer_New(Py_ssize_t size)
{
- PyObject *o;
- PyBufferObject * b;
+ PyObject *o;
+ PyBufferObject * b;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError,
- "size must be zero or positive");
- return NULL;
- }
- if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
- /* unlikely */
- return PyErr_NoMemory();
- }
- /* Inline PyObject_New */
- o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
- if ( o == NULL )
- return PyErr_NoMemory();
- b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
+ if (size < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "size must be zero or positive");
+ return NULL;
+ }
+ if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
+ /* unlikely */
+ return PyErr_NoMemory();
+ }
+ /* Inline PyObject_New */
+ o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
+ if ( o == NULL )
+ return PyErr_NoMemory();
+ b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
- b->b_base = NULL;
- b->b_ptr = (void *)(b + 1);
- b->b_size = size;
- b->b_offset = 0;
- b->b_readonly = 0;
- b->b_hash = -1;
+ b->b_base = NULL;
+ b->b_ptr = (void *)(b + 1);
+ b->b_size = size;
+ b->b_offset = 0;
+ b->b_readonly = 0;
+ b->b_hash = -1;
- return o;
+ return o;
}
/* Methods */
@@ -221,19 +221,21 @@
static PyObject *
buffer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
- PyObject *ob;
- Py_ssize_t offset = 0;
- Py_ssize_t size = Py_END_OF_BUFFER;
+ PyObject *ob;
+ Py_ssize_t offset = 0;
+ Py_ssize_t size = Py_END_OF_BUFFER;
- /*if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
- return NULL;*/
-
- if (!_PyArg_NoKeywords("buffer()", kw))
- return NULL;
+ /*
+ * if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
+ * return NULL;
+ */
- if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
- return NULL;
- return PyBuffer_FromObject(ob, offset, size);
+ if (!_PyArg_NoKeywords("buffer()", kw))
+ return NULL;
+
+ if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
+ return NULL;
+ return PyBuffer_FromObject(ob, offset, size);
}
PyDoc_STRVAR(buffer_doc,
@@ -248,99 +250,99 @@
static void
buffer_dealloc(PyBufferObject *self)
{
- Py_XDECREF(self->b_base);
- PyObject_DEL(self);
+ Py_XDECREF(self->b_base);
+ PyObject_DEL(self);
}
static int
buffer_compare(PyBufferObject *self, PyBufferObject *other)
{
- void *p1, *p2;
- Py_ssize_t len_self, len_other, min_len;
- int cmp;
+ void *p1, *p2;
+ Py_ssize_t len_self, len_other, min_len;
+ int cmp;
- if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
- return -1;
- if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
- return -1;
- min_len = (len_self < len_other) ? len_self : len_other;
- if (min_len > 0) {
- cmp = memcmp(p1, p2, min_len);
- if (cmp != 0)
- return cmp < 0 ? -1 : 1;
- }
- return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
+ if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
+ return -1;
+ if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
+ return -1;
+ min_len = (len_self < len_other) ? len_self : len_other;
+ if (min_len > 0) {
+ cmp = memcmp(p1, p2, min_len);
+ if (cmp != 0)
+ return cmp < 0 ? -1 : 1;
+ }
+ return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
}
static PyObject *
buffer_repr(PyBufferObject *self)
{
- const char *status = self->b_readonly ? "read-only" : "read-write";
+ const char *status = self->b_readonly ? "read-only" : "read-write";
if ( self->b_base == NULL )
- return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
- status,
- self->b_ptr,
- self->b_size,
- self);
- else
- return PyString_FromFormat(
- "<%s buffer for %p, size %zd, offset %zd at %p>",
- status,
- self->b_base,
- self->b_size,
- self->b_offset,
- self);
+ return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
+ status,
+ self->b_ptr,
+ self->b_size,
+ self);
+ else
+ return PyString_FromFormat(
+ "<%s buffer for %p, size %zd, offset %zd at %p>",
+ status,
+ self->b_base,
+ self->b_size,
+ self->b_offset,
+ self);
}
static long
buffer_hash(PyBufferObject *self)
{
- void *ptr;
- Py_ssize_t size;
- register Py_ssize_t len;
- register unsigned char *p;
- register long x;
+ void *ptr;
+ Py_ssize_t size;
+ register Py_ssize_t len;
+ register unsigned char *p;
+ register long x;
- if ( self->b_hash != -1 )
- return self->b_hash;
+ if ( self->b_hash != -1 )
+ return self->b_hash;
- /* XXX potential bugs here, a readonly buffer does not imply that the
- * underlying memory is immutable. b_readonly is a necessary but not
- * sufficient condition for a buffer to be hashable. Perhaps it would
- * be better to only allow hashing if the underlying object is known to
- * be immutable (e.g. PyString_Check() is true). Another idea would
- * be to call tp_hash on the underlying object and see if it raises
- * an error. */
- if ( !self->b_readonly )
- {
- PyErr_SetString(PyExc_TypeError,
- "writable buffers are not hashable");
- return -1;
- }
+ /* XXX potential bugs here, a readonly buffer does not imply that the
+ * underlying memory is immutable. b_readonly is a necessary but not
+ * sufficient condition for a buffer to be hashable. Perhaps it would
+ * be better to only allow hashing if the underlying object is known to
+ * be immutable (e.g. PyString_Check() is true). Another idea would
+ * be to call tp_hash on the underlying object and see if it raises
+ * an error. */
+ if ( !self->b_readonly )
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "writable buffers are not hashable");
+ return -1;
+ }
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return -1;
- p = (unsigned char *) ptr;
- len = size;
- x = *p << 7;
- while (--len >= 0)
- x = (1000003*x) ^ *p++;
- x ^= size;
- if (x == -1)
- x = -2;
- self->b_hash = x;
- return x;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return -1;
+ p = (unsigned char *) ptr;
+ len = size;
+ x = *p << 7;
+ while (--len >= 0)
+ x = (1000003*x) ^ *p++;
+ x ^= size;
+ if (x == -1)
+ x = -2;
+ self->b_hash = x;
+ return x;
}
static PyObject *
buffer_str(PyBufferObject *self)
{
- void *ptr;
- Py_ssize_t size;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return NULL;
- return PyString_FromStringAndSize((const char *)ptr, size);
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ return PyString_FromStringAndSize((const char *)ptr, size);
}
/* Sequence methods */
@@ -348,374 +350,372 @@
static Py_ssize_t
buffer_length(PyBufferObject *self)
{
- void *ptr;
- Py_ssize_t size;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return -1;
- return size;
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return -1;
+ return size;
}
static PyObject *
buffer_concat(PyBufferObject *self, PyObject *other)
{
- PyBufferProcs *pb = other->ob_type->tp_as_buffer;
- void *ptr1, *ptr2;
- char *p;
- PyObject *ob;
- Py_ssize_t size, count;
+ PyBufferProcs *pb = other->ob_type->tp_as_buffer;
+ void *ptr1, *ptr2;
+ char *p;
+ PyObject *ob;
+ Py_ssize_t size, count;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_BadArgument();
- return NULL;
- }
- if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
- {
- /* ### use a different exception type/message? */
- PyErr_SetString(PyExc_TypeError,
- "single-segment buffer object expected");
- return NULL;
- }
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return NULL;
+ }
- if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
- return NULL;
-
- /* optimize special case */
- if ( size == 0 )
- {
- Py_INCREF(other);
- return other;
- }
+ if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+ return NULL;
- if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
- return NULL;
+ /* optimize special case */
+ if ( size == 0 )
+ {
+ Py_INCREF(other);
+ return other;
+ }
- assert(count <= PY_SIZE_MAX - size);
+ if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+ return NULL;
- ob = PyString_FromStringAndSize(NULL, size + count);
- if ( ob == NULL )
- return NULL;
- p = PyString_AS_STRING(ob);
- memcpy(p, ptr1, size);
- memcpy(p + size, ptr2, count);
+ assert(count <= PY_SIZE_MAX - size);
- /* there is an extra byte in the string object, so this is safe */
- p[size + count] = '\0';
+ ob = PyString_FromStringAndSize(NULL, size + count);
+ if ( ob == NULL )
+ return NULL;
+ p = PyString_AS_STRING(ob);
+ memcpy(p, ptr1, size);
+ memcpy(p + size, ptr2, count);
- return ob;
+ /* there is an extra byte in the string object, so this is safe */
+ p[size + count] = '\0';
+
+ return ob;
}
static PyObject *
buffer_repeat(PyBufferObject *self, Py_ssize_t count)
{
- PyObject *ob;
- register char *p;
- void *ptr;
- Py_ssize_t size;
+ PyObject *ob;
+ register char *p;
+ void *ptr;
+ Py_ssize_t size;
- if ( count < 0 )
- count = 0;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return NULL;
- if (count > PY_SSIZE_T_MAX / size) {
- PyErr_SetString(PyExc_MemoryError, "result too large");
- return NULL;
- }
- ob = PyString_FromStringAndSize(NULL, size * count);
- if ( ob == NULL )
- return NULL;
+ if ( count < 0 )
+ count = 0;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ if (count > PY_SSIZE_T_MAX / size) {
+ PyErr_SetString(PyExc_MemoryError, "result too large");
+ return NULL;
+ }
+ ob = PyString_FromStringAndSize(NULL, size * count);
+ if ( ob == NULL )
+ return NULL;
- p = PyString_AS_STRING(ob);
- while ( count-- )
- {
- memcpy(p, ptr, size);
- p += size;
- }
+ p = PyString_AS_STRING(ob);
+ while ( count-- )
+ {
+ memcpy(p, ptr, size);
+ p += size;
+ }
- /* there is an extra byte in the string object, so this is safe */
- *p = '\0';
+ /* there is an extra byte in the string object, so this is safe */
+ *p = '\0';
- return ob;
+ return ob;
}
static PyObject *
buffer_item(PyBufferObject *self, Py_ssize_t idx)
{
- void *ptr;
- Py_ssize_t size;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return NULL;
- if ( idx < 0 || idx >= size ) {
- PyErr_SetString(PyExc_IndexError, "buffer index out of range");
- return NULL;
- }
- return PyString_FromStringAndSize((char *)ptr + idx, 1);
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ if ( idx < 0 || idx >= size ) {
+ PyErr_SetString(PyExc_IndexError, "buffer index out of range");
+ return NULL;
+ }
+ return PyString_FromStringAndSize((char *)ptr + idx, 1);
}
static PyObject *
buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
{
- void *ptr;
- Py_ssize_t size;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return NULL;
- if ( left < 0 )
- left = 0;
- if ( right < 0 )
- right = 0;
- if ( right > size )
- right = size;
- if ( right < left )
- right = left;
- return PyString_FromStringAndSize((char *)ptr + left,
- right - left);
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ if ( left < 0 )
+ left = 0;
+ if ( right < 0 )
+ right = 0;
+ if ( right > size )
+ right = size;
+ if ( right < left )
+ right = left;
+ return PyString_FromStringAndSize((char *)ptr + left,
+ right - left);
}
static PyObject *
buffer_subscript(PyBufferObject *self, PyObject *item)
{
- void *p;
- Py_ssize_t size;
-
- if (!get_buf(self, &p, &size, ANY_BUFFER))
- return NULL;
-
+ void *p;
+ Py_ssize_t size;
+
+ if (!get_buf(self, &p, &size, ANY_BUFFER))
+ return NULL;
if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
- if (i == -1 && PyErr_Occurred())
- return NULL;
- if (i < 0)
- i += size;
- return buffer_item(self, i);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength, cur, i;
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += size;
+ return buffer_item(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength, cur, i;
- if (PySlice_GetIndicesEx((PySliceObject*)item, size,
- &start, &stop, &step, &slicelength) < 0) {
- return NULL;
- }
+ if (PySlice_GetIndicesEx((PySliceObject*)item, size,
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
- if (slicelength <= 0)
- return PyString_FromStringAndSize("", 0);
- else if (step == 1)
- return PyString_FromStringAndSize((char *)p + start,
- stop - start);
- else {
- PyObject *result;
- char *source_buf = (char *)p;
- char *result_buf = (char *)PyMem_Malloc(slicelength);
+ if (slicelength <= 0)
+ return PyString_FromStringAndSize("", 0);
+ else if (step == 1)
+ return PyString_FromStringAndSize((char *)p + start,
+ stop - start);
+ else {
+ PyObject *result;
+ char *source_buf = (char *)p;
+ char *result_buf = (char *)PyMem_Malloc(slicelength);
- if (result_buf == NULL)
- return PyErr_NoMemory();
+ if (result_buf == NULL)
+ return PyErr_NoMemory();
- for (cur = start, i = 0; i < slicelength;
- cur += step, i++) {
- result_buf[i] = source_buf[cur];
- }
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ result_buf[i] = source_buf[cur];
+ }
- result = PyString_FromStringAndSize(result_buf,
- slicelength);
- PyMem_Free(result_buf);
- return result;
- }
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "sequence index must be integer");
- return NULL;
- }
+ result = PyString_FromStringAndSize(result_buf,
+ slicelength);
+ PyMem_Free(result_buf);
+ return result;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "sequence index must be integer");
+ return NULL;
+ }
}
static int
buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
{
- PyBufferProcs *pb;
- void *ptr1, *ptr2;
- Py_ssize_t size;
- Py_ssize_t count;
+ PyBufferProcs *pb;
+ void *ptr1, *ptr2;
+ Py_ssize_t size;
+ Py_ssize_t count;
- if ( self->b_readonly ) {
- PyErr_SetString(PyExc_TypeError,
- "buffer is read-only");
- return -1;
- }
+ if ( self->b_readonly ) {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer is read-only");
+ return -1;
+ }
- if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
- return -1;
+ if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+ return -1;
- if (idx < 0 || idx >= size) {
- PyErr_SetString(PyExc_IndexError,
- "buffer assignment index out of range");
- return -1;
- }
+ if (idx < 0 || idx >= size) {
+ PyErr_SetString(PyExc_IndexError,
+ "buffer assignment index out of range");
+ return -1;
+ }
- pb = other ? other->ob_type->tp_as_buffer : NULL;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_BadArgument();
- return -1;
- }
- if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
- {
- /* ### use a different exception type/message? */
- PyErr_SetString(PyExc_TypeError,
- "single-segment buffer object expected");
- return -1;
- }
+ pb = other ? other->ob_type->tp_as_buffer : NULL;
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return -1;
+ }
+ if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return -1;
+ }
- if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
- return -1;
- if ( count != 1 ) {
- PyErr_SetString(PyExc_TypeError,
- "right operand must be a single byte");
- return -1;
- }
+ if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+ return -1;
+ if ( count != 1 ) {
+ PyErr_SetString(PyExc_TypeError,
+ "right operand must be a single byte");
+ return -1;
+ }
- ((char *)ptr1)[idx] = *(char *)ptr2;
- return 0;
+ ((char *)ptr1)[idx] = *(char *)ptr2;
+ return 0;
}
static int
buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
{
- PyBufferProcs *pb;
- void *ptr1, *ptr2;
- Py_ssize_t size;
- Py_ssize_t slice_len;
- Py_ssize_t count;
+ PyBufferProcs *pb;
+ void *ptr1, *ptr2;
+ Py_ssize_t size;
+ Py_ssize_t slice_len;
+ Py_ssize_t count;
- if ( self->b_readonly ) {
- PyErr_SetString(PyExc_TypeError,
- "buffer is read-only");
- return -1;
- }
+ if ( self->b_readonly ) {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer is read-only");
+ return -1;
+ }
- pb = other ? other->ob_type->tp_as_buffer : NULL;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_BadArgument();
- return -1;
- }
- if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
- {
- /* ### use a different exception type/message? */
- PyErr_SetString(PyExc_TypeError,
- "single-segment buffer object expected");
- return -1;
- }
- if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
- return -1;
- if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
- return -1;
+ pb = other ? other->ob_type->tp_as_buffer : NULL;
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return -1;
+ }
+ if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return -1;
+ }
+ if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+ return -1;
+ if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+ return -1;
- if ( left < 0 )
- left = 0;
- else if ( left > size )
- left = size;
- if ( right < left )
- right = left;
- else if ( right > size )
- right = size;
- slice_len = right - left;
+ if ( left < 0 )
+ left = 0;
+ else if ( left > size )
+ left = size;
+ if ( right < left )
+ right = left;
+ else if ( right > size )
+ right = size;
+ slice_len = right - left;
- if ( count != slice_len ) {
- PyErr_SetString(
- PyExc_TypeError,
- "right operand length must match slice length");
- return -1;
- }
+ if ( count != slice_len ) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "right operand length must match slice length");
+ return -1;
+ }
- if ( slice_len )
- memcpy((char *)ptr1 + left, ptr2, slice_len);
+ if ( slice_len )
+ memcpy((char *)ptr1 + left, ptr2, slice_len);
- return 0;
+ return 0;
}
static int
buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
{
- PyBufferProcs *pb;
- void *ptr1, *ptr2;
- Py_ssize_t selfsize;
- Py_ssize_t othersize;
+ PyBufferProcs *pb;
+ void *ptr1, *ptr2;
+ Py_ssize_t selfsize;
+ Py_ssize_t othersize;
- if ( self->b_readonly ) {
- PyErr_SetString(PyExc_TypeError,
- "buffer is read-only");
- return -1;
- }
+ if ( self->b_readonly ) {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer is read-only");
+ return -1;
+ }
- pb = value ? value->ob_type->tp_as_buffer : NULL;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_BadArgument();
- return -1;
- }
- if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
- {
- /* ### use a different exception type/message? */
- PyErr_SetString(PyExc_TypeError,
- "single-segment buffer object expected");
- return -1;
- }
- if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
- return -1;
-
+ pb = value ? value->ob_type->tp_as_buffer : NULL;
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return -1;
+ }
+ if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return -1;
+ }
+ if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
+ return -1;
if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
- if (i == -1 && PyErr_Occurred())
- return -1;
- if (i < 0)
- i += selfsize;
- return buffer_ass_item(self, i, value);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
- &start, &stop, &step, &slicelength) < 0)
- return -1;
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return -1;
+ if (i < 0)
+ i += selfsize;
+ return buffer_ass_item(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
- if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
- return -1;
+ if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
+ &start, &stop, &step, &slicelength) < 0)
+ return -1;
- if (othersize != slicelength) {
- PyErr_SetString(
- PyExc_TypeError,
- "right operand length must match slice length");
- return -1;
- }
+ if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
+ return -1;
- if (slicelength == 0)
- return 0;
- else if (step == 1) {
- memcpy((char *)ptr1 + start, ptr2, slicelength);
- return 0;
- }
- else {
- Py_ssize_t cur, i;
-
- for (cur = start, i = 0; i < slicelength;
- cur += step, i++) {
- ((char *)ptr1)[cur] = ((char *)ptr2)[i];
- }
+ if (othersize != slicelength) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "right operand length must match slice length");
+ return -1;
+ }
- return 0;
- }
- } else {
- PyErr_SetString(PyExc_TypeError,
- "buffer indices must be integers");
- return -1;
- }
+ if (slicelength == 0)
+ return 0;
+ else if (step == 1) {
+ memcpy((char *)ptr1 + start, ptr2, slicelength);
+ return 0;
+ }
+ else {
+ Py_ssize_t cur, i;
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ ((char *)ptr1)[cur] = ((char *)ptr2)[i];
+ }
+
+ return 0;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer indices must be integers");
+ return -1;
+ }
}
/* Buffer methods */
@@ -723,64 +723,64 @@
static Py_ssize_t
buffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
{
- Py_ssize_t size;
- if ( idx != 0 ) {
- PyErr_SetString(PyExc_SystemError,
- "accessing non-existent buffer segment");
- return -1;
- }
- if (!get_buf(self, pp, &size, READ_BUFFER))
- return -1;
- return size;
+ Py_ssize_t size;
+ if ( idx != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent buffer segment");
+ return -1;
+ }
+ if (!get_buf(self, pp, &size, READ_BUFFER))
+ return -1;
+ return size;
}
static Py_ssize_t
buffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
{
- Py_ssize_t size;
+ Py_ssize_t size;
- if ( self->b_readonly )
- {
- PyErr_SetString(PyExc_TypeError, "buffer is read-only");
- return -1;
- }
+ if ( self->b_readonly )
+ {
+ PyErr_SetString(PyExc_TypeError, "buffer is read-only");
+ return -1;
+ }
- if ( idx != 0 ) {
- PyErr_SetString(PyExc_SystemError,
- "accessing non-existent buffer segment");
- return -1;
- }
- if (!get_buf(self, pp, &size, WRITE_BUFFER))
- return -1;
- return size;
+ if ( idx != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent buffer segment");
+ return -1;
+ }
+ if (!get_buf(self, pp, &size, WRITE_BUFFER))
+ return -1;
+ return size;
}
static Py_ssize_t
buffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp)
{
- void *ptr;
- Py_ssize_t size;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return -1;
- if (lenp)
- *lenp = size;
- return 1;
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return -1;
+ if (lenp)
+ *lenp = size;
+ return 1;
}
static Py_ssize_t
buffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp)
{
- void *ptr;
- Py_ssize_t size;
- if ( idx != 0 ) {
- PyErr_SetString(PyExc_SystemError,
- "accessing non-existent buffer segment");
- return -1;
- }
- if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
- return -1;
- *pp = (const char *)ptr;
- return size;
+ void *ptr;
+ Py_ssize_t size;
+ if ( idx != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent buffer segment");
+ return -1;
+ }
+ if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
+ return -1;
+ *pp = (const char *)ptr;
+ return size;
}
void init_bufferobject(void)
@@ -789,67 +789,65 @@
}
static PySequenceMethods buffer_as_sequence = {
- (lenfunc)buffer_length, /*sq_length*/
- (binaryfunc)buffer_concat, /*sq_concat*/
- (ssizeargfunc)buffer_repeat, /*sq_repeat*/
- (ssizeargfunc)buffer_item, /*sq_item*/
- (ssizessizeargfunc)buffer_slice, /*sq_slice*/
- (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
- (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
+ (lenfunc)buffer_length, /*sq_length*/
+ (binaryfunc)buffer_concat, /*sq_concat*/
+ (ssizeargfunc)buffer_repeat, /*sq_repeat*/
+ (ssizeargfunc)buffer_item, /*sq_item*/
+ (ssizessizeargfunc)buffer_slice, /*sq_slice*/
+ (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
+ (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
};
static PyMappingMethods buffer_as_mapping = {
- (lenfunc)buffer_length,
- (binaryfunc)buffer_subscript,
- (objobjargproc)buffer_ass_subscript,
+ (lenfunc)buffer_length,
+ (binaryfunc)buffer_subscript,
+ (objobjargproc)buffer_ass_subscript,
};
static PyBufferProcs buffer_as_buffer = {
- (readbufferproc)buffer_getreadbuf,
- (writebufferproc)buffer_getwritebuf,
- (segcountproc)buffer_getsegcount,
- (charbufferproc)buffer_getcharbuf,
+ (readbufferproc)buffer_getreadbuf,
+ (writebufferproc)buffer_getwritebuf,
+ (segcountproc)buffer_getsegcount,
+ (charbufferproc)buffer_getcharbuf,
};
PyTypeObject PyBuffer_Type = {
- PyObject_HEAD_INIT(NULL)
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "buffer",
+ sizeof(PyBufferObject),
0,
- "buffer",
- sizeof(PyBufferObject),
- 0,
- (destructor)buffer_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- (cmpfunc)buffer_compare, /* tp_compare */
- (reprfunc)buffer_repr, /* tp_repr */
- 0, /* tp_as_number */
- &buffer_as_sequence, /* tp_as_sequence */
- &buffer_as_mapping, /* tp_as_mapping */
- (hashfunc)buffer_hash, /* tp_hash */
- 0, /* tp_call */
- (reprfunc)buffer_str, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- &buffer_as_buffer, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER, /* tp_flags */
- buffer_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- buffer_new, /* tp_new */
+ (destructor)buffer_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)buffer_compare, /* tp_compare */
+ (reprfunc)buffer_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &buffer_as_sequence, /* tp_as_sequence */
+ &buffer_as_mapping, /* tp_as_mapping */
+ (hashfunc)buffer_hash, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)buffer_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ &buffer_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER, /* tp_flags */
+ buffer_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ buffer_new, /* tp_new */
};
-
diff --git a/pypy/module/cpyext/src/cobject.c b/pypy/module/cpyext/src/cobject.c
--- a/pypy/module/cpyext/src/cobject.c
+++ b/pypy/module/cpyext/src/cobject.c
@@ -50,6 +50,10 @@
PyCObject_AsVoidPtr(PyObject *self)
{
if (self) {
+ if (PyCapsule_CheckExact(self)) {
+ const char *name = PyCapsule_GetName(self);
+ return (void *)PyCapsule_GetPointer(self, name);
+ }
if (self->ob_type == &PyCObject_Type)
return ((PyCObject *)self)->cobject;
PyErr_SetString(PyExc_TypeError,
diff --git a/pypy/module/cpyext/src/getargs.c b/pypy/module/cpyext/src/getargs.c
--- a/pypy/module/cpyext/src/getargs.c
+++ b/pypy/module/cpyext/src/getargs.c
@@ -7,349 +7,348 @@
#ifdef __cplusplus
-extern "C" {
+extern "C" {
#endif
-
int PyArg_Parse(PyObject *, const char *, ...);
int PyArg_ParseTuple(PyObject *, const char *, ...);
int PyArg_VaParse(PyObject *, const char *, va_list);
int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
- const char *, char **, ...);
+ const char *, char **, ...);
int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
- const char *, char **, va_list);
+ const char *, char **, va_list);
#define FLAG_COMPAT 1
#define FLAG_SIZE_T 2
-typedef int (*destr_t)(PyObject *, void *);
-
-
-/* Keep track of "objects" that have been allocated or initialized and
- which will need to be deallocated or cleaned up somehow if overall
- parsing fails.
-*/
-typedef struct {
- void *item;
- destr_t destructor;
-} freelistentry_t;
-
-typedef struct {
- int first_available;
- freelistentry_t *entries;
-} freelist_t;
-
/* Forward */
static int vgetargs1(PyObject *, const char *, va_list *, int);
static void seterror(int, const char *, int *, const char *, const char *);
-static char *convertitem(PyObject *, const char **, va_list *, int, int *,
- char *, size_t, freelist_t *);
+static char *convertitem(PyObject *, const char **, va_list *, int, int *,
+ char *, size_t, PyObject **);
static char *converttuple(PyObject *, const char **, va_list *, int,
- int *, char *, size_t, int, freelist_t *);
+ int *, char *, size_t, int, PyObject **);
static char *convertsimple(PyObject *, const char **, va_list *, int, char *,
- size_t, freelist_t *);
+ size_t, PyObject **);
static Py_ssize_t convertbuffer(PyObject *, void **p, char **);
static int getbuffer(PyObject *, Py_buffer *, char**);
static int vgetargskeywords(PyObject *, PyObject *,
- const char *, char **, va_list *, int);
+ const char *, char **, va_list *, int);
static char *skipitem(const char **, va_list *, int);
int
PyArg_Parse(PyObject *args, const char *format, ...)
{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, FLAG_COMPAT);
- va_end(va);
- return retval;
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, FLAG_COMPAT);
+ va_end(va);
+ return retval;
}
int
_PyArg_Parse_SizeT(PyObject *args, char *format, ...)
{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
- va_end(va);
- return retval;
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
+ va_end(va);
+ return retval;
}
int
PyArg_ParseTuple(PyObject *args, const char *format, ...)
{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, 0);
- va_end(va);
- return retval;
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, 0);
+ va_end(va);
+ return retval;
}
int
_PyArg_ParseTuple_SizeT(PyObject *args, char *format, ...)
{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
- va_end(va);
- return retval;
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
+ va_end(va);
+ return retval;
}
int
PyArg_VaParse(PyObject *args, const char *format, va_list va)
{
- va_list lva;
+ va_list lva;
#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
+ memcpy(lva, va, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(lva, va);
+ __va_copy(lva, va);
#else
- lva = va;
+ lva = va;
#endif
#endif
- return vgetargs1(args, format, &lva, 0);
+ return vgetargs1(args, format, &lva, 0);
}
int
_PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
{
- va_list lva;
+ va_list lva;
#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
+ memcpy(lva, va, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(lva, va);
+ __va_copy(lva, va);
#else
- lva = va;
+ lva = va;
#endif
#endif
- return vgetargs1(args, format, &lva, FLAG_SIZE_T);
+ return vgetargs1(args, format, &lva, FLAG_SIZE_T);
}
/* Handle cleanup of allocated memory in case of exception */
+#define GETARGS_CAPSULE_NAME_CLEANUP_PTR "getargs.cleanup_ptr"
+#define GETARGS_CAPSULE_NAME_CLEANUP_BUFFER "getargs.cleanup_buffer"
+
+static void
+cleanup_ptr(PyObject *self)
+{
+ void *ptr = PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_PTR);
+ if (ptr) {
+ PyMem_FREE(ptr);
+ }
+}
+
+static void
+cleanup_buffer(PyObject *self)
+{
+ Py_buffer *ptr = (Py_buffer *)PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_BUFFER);
+ if (ptr) {
+ PyBuffer_Release(ptr);
+ }
+}
+
static int
-cleanup_ptr(PyObject *self, void *ptr)
+addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
{
- if (ptr) {
- PyMem_FREE(ptr);
+ PyObject *cobj;
+ const char *name;
+
+ if (!*freelist) {
+ *freelist = PyList_New(0);
+ if (!*freelist) {
+ destr(ptr);
+ return -1;
+ }
}
+
+ if (destr == cleanup_ptr) {
+ name = GETARGS_CAPSULE_NAME_CLEANUP_PTR;
+ } else if (destr == cleanup_buffer) {
+ name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER;
+ } else {
+ return -1;
+ }
+ cobj = PyCapsule_New(ptr, name, destr);
+ if (!cobj) {
+ destr(ptr);
+ return -1;
+ }
+ if (PyList_Append(*freelist, cobj)) {
+ Py_DECREF(cobj);
+ return -1;
+ }
+ Py_DECREF(cobj);
return 0;
}
static int
-cleanup_buffer(PyObject *self, void *ptr)
+cleanreturn(int retval, PyObject *freelist)
{
- Py_buffer *buf = (Py_buffer *)ptr;
- if (buf) {
- PyBuffer_Release(buf);
+ if (freelist && retval != 0) {
+ /* We were successful, reset the destructors so that they
+ don't get called. */
+ Py_ssize_t len = PyList_GET_SIZE(freelist), i;
+ for (i = 0; i < len; i++)
+ PyCapsule_SetDestructor(PyList_GET_ITEM(freelist, i), NULL);
}
- return 0;
+ Py_XDECREF(freelist);
+ return retval;
}
-static int
-addcleanup(void *ptr, freelist_t *freelist, destr_t destructor)
-{
- int index;
-
- index = freelist->first_available;
- freelist->first_available += 1;
-
- freelist->entries[index].item = ptr;
- freelist->entries[index].destructor = destructor;
-
- return 0;
-}
-
-static int
-cleanreturn(int retval, freelist_t *freelist)
-{
- int index;
-
- if (retval == 0) {
- /* A failure occurred, therefore execute all of the cleanup
- functions.
- */
- for (index = 0; index < freelist->first_available; ++index) {
- freelist->entries[index].destructor(NULL,
- freelist->entries[index].item);
- }
- }
- PyMem_Free(freelist->entries);
- return retval;
-}
static int
vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
{
- char msgbuf[256];
- int levels[32];
- const char *fname = NULL;
- const char *message = NULL;
- int min = -1;
- int max = 0;
- int level = 0;
- int endfmt = 0;
- const char *formatsave = format;
- Py_ssize_t i, len;
- char *msg;
- freelist_t freelist = {0, NULL};
- int compat = flags & FLAG_COMPAT;
+ char msgbuf[256];
+ int levels[32];
+ const char *fname = NULL;
+ const char *message = NULL;
+ int min = -1;
+ int max = 0;
+ int level = 0;
+ int endfmt = 0;
+ const char *formatsave = format;
+ Py_ssize_t i, len;
+ char *msg;
+ PyObject *freelist = NULL;
+ int compat = flags & FLAG_COMPAT;
- assert(compat || (args != (PyObject*)NULL));
- flags = flags & ~FLAG_COMPAT;
+ assert(compat || (args != (PyObject*)NULL));
+ flags = flags & ~FLAG_COMPAT;
- while (endfmt == 0) {
- int c = *format++;
- switch (c) {
- case '(':
- if (level == 0)
- max++;
- level++;
- if (level >= 30)
- Py_FatalError("too many tuple nesting levels "
- "in argument format string");
- break;
- case ')':
- if (level == 0)
- Py_FatalError("excess ')' in getargs format");
- else
- level--;
- break;
- case '\0':
- endfmt = 1;
- break;
- case ':':
- fname = format;
- endfmt = 1;
- break;
- case ';':
- message = format;
- endfmt = 1;
- break;
- default:
- if (level == 0) {
- if (c == 'O')
- max++;
- else if (isalpha(Py_CHARMASK(c))) {
- if (c != 'e') /* skip encoded */
- max++;
- } else if (c == '|')
- min = max;
- }
- break;
- }
- }
-
- if (level != 0)
- Py_FatalError(/* '(' */ "missing ')' in getargs format");
-
- if (min < 0)
- min = max;
-
- format = formatsave;
-
- freelist.entries = PyMem_New(freelistentry_t, max);
+ while (endfmt == 0) {
+ int c = *format++;
+ switch (c) {
+ case '(':
+ if (level == 0)
+ max++;
+ level++;
+ if (level >= 30)
+ Py_FatalError("too many tuple nesting levels "
+ "in argument format string");
+ break;
+ case ')':
+ if (level == 0)
+ Py_FatalError("excess ')' in getargs format");
+ else
+ level--;
+ break;
+ case '\0':
+ endfmt = 1;
+ break;
+ case ':':
+ fname = format;
+ endfmt = 1;
+ break;
+ case ';':
+ message = format;
+ endfmt = 1;
+ break;
+ default:
+ if (level == 0) {
+ if (c == 'O')
+ max++;
+ else if (isalpha(Py_CHARMASK(c))) {
+ if (c != 'e') /* skip encoded */
+ max++;
+ } else if (c == '|')
+ min = max;
+ }
+ break;
+ }
+ }
- if (compat) {
- if (max == 0) {
- if (args == NULL)
- return cleanreturn(1, &freelist);
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.200s%s takes no arguments",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()");
- PyErr_SetString(PyExc_TypeError, msgbuf);
- return cleanreturn(0, &freelist);
- }
- else if (min == 1 && max == 1) {
- if (args == NULL) {
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.200s%s takes at least one argument",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()");
- PyErr_SetString(PyExc_TypeError, msgbuf);
- return cleanreturn(0, &freelist);
- }
- msg = convertitem(args, &format, p_va, flags, levels,
- msgbuf, sizeof(msgbuf), &freelist);
- if (msg == NULL)
- return cleanreturn(1, &freelist);
- seterror(levels[0], msg, levels+1, fname, message);
- return cleanreturn(0, &freelist);
- }
- else {
- PyErr_SetString(PyExc_SystemError,
- "old style getargs format uses new features");
- return cleanreturn(0, &freelist);
- }
- }
-
- if (!PyTuple_Check(args)) {
- PyErr_SetString(PyExc_SystemError,
- "new style getargs format but argument is not a tuple");
- return cleanreturn(0, &freelist);
- }
-
- len = PyTuple_GET_SIZE(args);
-
- if (len < min || max < len) {
- if (message == NULL) {
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.150s%s takes %s %d argument%s "
- "(%ld given)",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()",
- min==max ? "exactly"
- : len < min ? "at least" : "at most",
- len < min ? min : max,
- (len < min ? min : max) == 1 ? "" : "s",
- Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
- message = msgbuf;
- }
- PyErr_SetString(PyExc_TypeError, message);
- return cleanreturn(0, &freelist);
- }
-
- for (i = 0; i < len; i++) {
- if (*format == '|')
- format++;
- msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
- flags, levels, msgbuf,
- sizeof(msgbuf), &freelist);
- if (msg) {
- seterror(i+1, msg, levels, fname, message);
- return cleanreturn(0, &freelist);
- }
- }
+ if (level != 0)
+ Py_FatalError(/* '(' */ "missing ')' in getargs format");
- if (*format != '\0' && !isalpha(Py_CHARMASK(*format)) &&
- *format != '(' &&
- *format != '|' && *format != ':' && *format != ';') {
- PyErr_Format(PyExc_SystemError,
- "bad format string: %.200s", formatsave);
- return cleanreturn(0, &freelist);
- }
-
- return cleanreturn(1, &freelist);
+ if (min < 0)
+ min = max;
+
+ format = formatsave;
+
+ if (compat) {
+ if (max == 0) {
+ if (args == NULL)
+ return 1;
+ PyOS_snprintf(msgbuf, sizeof(msgbuf),
+ "%.200s%s takes no arguments",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()");
+ PyErr_SetString(PyExc_TypeError, msgbuf);
+ return 0;
+ }
+ else if (min == 1 && max == 1) {
+ if (args == NULL) {
+ PyOS_snprintf(msgbuf, sizeof(msgbuf),
+ "%.200s%s takes at least one argument",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()");
+ PyErr_SetString(PyExc_TypeError, msgbuf);
+ return 0;
+ }
+ msg = convertitem(args, &format, p_va, flags, levels,
+ msgbuf, sizeof(msgbuf), &freelist);
+ if (msg == NULL)
+ return cleanreturn(1, freelist);
+ seterror(levels[0], msg, levels+1, fname, message);
+ return cleanreturn(0, freelist);
+ }
+ else {
+ PyErr_SetString(PyExc_SystemError,
+ "old style getargs format uses new features");
+ return 0;
+ }
+ }
+
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_SystemError,
+ "new style getargs format but argument is not a tuple");
+ return 0;
+ }
+
+ len = PyTuple_GET_SIZE(args);
+
+ if (len < min || max < len) {
+ if (message == NULL) {
+ PyOS_snprintf(msgbuf, sizeof(msgbuf),
+ "%.150s%s takes %s %d argument%s "
+ "(%ld given)",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()",
+ min==max ? "exactly"
+ : len < min ? "at least" : "at most",
+ len < min ? min : max,
+ (len < min ? min : max) == 1 ? "" : "s",
+ Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
+ message = msgbuf;
+ }
+ PyErr_SetString(PyExc_TypeError, message);
+ return 0;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (*format == '|')
+ format++;
+ msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
+ flags, levels, msgbuf,
+ sizeof(msgbuf), &freelist);
+ if (msg) {
+ seterror(i+1, msg, levels, fname, msg);
+ return cleanreturn(0, freelist);
+ }
+ }
+
+ if (*format != '\0' && !isalpha(Py_CHARMASK(*format)) &&
+ *format != '(' &&
+ *format != '|' && *format != ':' && *format != ';') {
+ PyErr_Format(PyExc_SystemError,
+ "bad format string: %.200s", formatsave);
+ return cleanreturn(0, freelist);
+ }
+
+ return cleanreturn(1, freelist);
}
@@ -358,37 +357,37 @@
seterror(int iarg, const char *msg, int *levels, const char *fname,
const char *message)
{
- char buf[512];
- int i;
- char *p = buf;
+ char buf[512];
+ int i;
+ char *p = buf;
- if (PyErr_Occurred())
- return;
- else if (message == NULL) {
- if (fname != NULL) {
- PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
- p += strlen(p);
- }
- if (iarg != 0) {
- PyOS_snprintf(p, sizeof(buf) - (p - buf),
- "argument %d", iarg);
- i = 0;
- p += strlen(p);
- while (levels[i] > 0 && i < 32 && (int)(p-buf) < 220) {
- PyOS_snprintf(p, sizeof(buf) - (p - buf),
- ", item %d", levels[i]-1);
- p += strlen(p);
- i++;
- }
- }
- else {
- PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
- p += strlen(p);
- }
- PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
- message = buf;
- }
- PyErr_SetString(PyExc_TypeError, message);
+ if (PyErr_Occurred())
+ return;
+ else if (message == NULL) {
+ if (fname != NULL) {
+ PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
+ p += strlen(p);
+ }
+ if (iarg != 0) {
+ PyOS_snprintf(p, sizeof(buf) - (p - buf),
+ "argument %d", iarg);
+ i = 0;
+ p += strlen(p);
+ while (levels[i] > 0 && i < 32 && (int)(p-buf) < 220) {
+ PyOS_snprintf(p, sizeof(buf) - (p - buf),
+ ", item %d", levels[i]-1);
+ p += strlen(p);
+ i++;
+ }
+ }
+ else {
+ PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
+ p += strlen(p);
+ }
+ PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
+ message = buf;
+ }
+ PyErr_SetString(PyExc_TypeError, message);
}
@@ -404,85 +403,84 @@
*p_va is undefined,
*levels is a 0-terminated list of item numbers,
*msgbuf contains an error message, whose format is:
- "must be <typename1>, not <typename2>", where:
- <typename1> is the name of the expected type, and
- <typename2> is the name of the actual type,
+ "must be <typename1>, not <typename2>", where:
+ <typename1> is the name of the expected type, and
+ <typename2> is the name of the actual type,
and msgbuf is returned.
*/
static char *
converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
- int *levels, char *msgbuf, size_t bufsize, int toplevel,
- freelist_t *freelist)
+ int *levels, char *msgbuf, size_t bufsize, int toplevel,
+ PyObject **freelist)
{
- int level = 0;
- int n = 0;
- const char *format = *p_format;
- int i;
-
- for (;;) {
- int c = *format++;
- if (c == '(') {
- if (level == 0)
- n++;
- level++;
- }
- else if (c == ')') {
- if (level == 0)
- break;
- level--;
- }
- else if (c == ':' || c == ';' || c == '\0')
- break;
- else if (level == 0 && isalpha(Py_CHARMASK(c)))
- n++;
- }
-
- if (!PySequence_Check(arg) || PyString_Check(arg)) {
- levels[0] = 0;
- PyOS_snprintf(msgbuf, bufsize,
- toplevel ? "expected %d arguments, not %.50s" :
- "must be %d-item sequence, not %.50s",
- n,
- arg == Py_None ? "None" : arg->ob_type->tp_name);
- return msgbuf;
- }
-
- if ((i = PySequence_Size(arg)) != n) {
- levels[0] = 0;
- PyOS_snprintf(msgbuf, bufsize,
- toplevel ? "expected %d arguments, not %d" :
- "must be sequence of length %d, not %d",
- n, i);
- return msgbuf;
- }
+ int level = 0;
+ int n = 0;
+ const char *format = *p_format;
+ int i;
- format = *p_format;
- for (i = 0; i < n; i++) {
- char *msg;
- PyObject *item;
+ for (;;) {
+ int c = *format++;
+ if (c == '(') {
+ if (level == 0)
+ n++;
+ level++;
+ }
+ else if (c == ')') {
+ if (level == 0)
+ break;
+ level--;
+ }
+ else if (c == ':' || c == ';' || c == '\0')
+ break;
+ else if (level == 0 && isalpha(Py_CHARMASK(c)))
+ n++;
+ }
+
+ if (!PySequence_Check(arg) || PyString_Check(arg)) {
+ levels[0] = 0;
+ PyOS_snprintf(msgbuf, bufsize,
+ toplevel ? "expected %d arguments, not %.50s" :
+ "must be %d-item sequence, not %.50s",
+ n,
+ arg == Py_None ? "None" : arg->ob_type->tp_name);
+ return msgbuf;
+ }
+
+ if ((i = PySequence_Size(arg)) != n) {
+ levels[0] = 0;
+ PyOS_snprintf(msgbuf, bufsize,
+ toplevel ? "expected %d arguments, not %d" :
+ "must be sequence of length %d, not %d",
+ n, i);
+ return msgbuf;
+ }
+
+ format = *p_format;
+ for (i = 0; i < n; i++) {
+ char *msg;
+ PyObject *item;
item = PySequence_GetItem(arg, i);
- if (item == NULL) {
- PyErr_Clear();
- levels[0] = i+1;
- levels[1] = 0;
- strncpy(msgbuf, "is not retrievable",
- bufsize);
- return msgbuf;
- }
- PyPy_Borrow(arg, item);
- msg = convertitem(item, &format, p_va, flags, levels+1,
- msgbuf, bufsize, freelist);
+ if (item == NULL) {
+ PyErr_Clear();
+ levels[0] = i+1;
+ levels[1] = 0;
+ strncpy(msgbuf, "is not retrievable", bufsize);
+ return msgbuf;
+ }
+ PyPy_Borrow(arg, item);
+ msg = convertitem(item, &format, p_va, flags, levels+1,
+ msgbuf, bufsize, freelist);
/* PySequence_GetItem calls tp->sq_item, which INCREFs */
Py_XDECREF(item);
- if (msg != NULL) {
- levels[0] = i+1;
- return msg;
- }
- }
+ if (msg != NULL) {
+ levels[0] = i+1;
+ return msg;
+ }
+ }
- *p_format = format;
- return NULL;
+ *p_format = format;
+ return NULL;
}
@@ -490,45 +488,45 @@
static char *
convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
- int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist)
+ int *levels, char *msgbuf, size_t bufsize, PyObject **freelist)
{
- char *msg;
- const char *format = *p_format;
-
- if (*format == '(' /* ')' */) {
- format++;
- msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
- bufsize, 0, freelist);
- if (msg == NULL)
- format++;
- }
- else {
- msg = convertsimple(arg, &format, p_va, flags,
- msgbuf, bufsize, freelist);
- if (msg != NULL)
- levels[0] = 0;
- }
- if (msg == NULL)
- *p_format = format;
- return msg;
+ char *msg;
+ const char *format = *p_format;
+
+ if (*format == '(' /* ')' */) {
+ format++;
+ msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
+ bufsize, 0, freelist);
+ if (msg == NULL)
+ format++;
+ }
+ else {
+ msg = convertsimple(arg, &format, p_va, flags,
+ msgbuf, bufsize, freelist);
+ if (msg != NULL)
+ levels[0] = 0;
+ }
+ if (msg == NULL)
+ *p_format = format;
+ return msg;
}
#define UNICODE_DEFAULT_ENCODING(arg) \
- _PyUnicode_AsDefaultEncodedString(arg, NULL)
+ _PyUnicode_AsDefaultEncodedString(arg, NULL)
/* Format an error message generated by convertsimple(). */
static char *
converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
{
- assert(expected != NULL);
- assert(arg != NULL);
- PyOS_snprintf(msgbuf, bufsize,
- "must be %.50s, not %.50s", expected,
- arg == Py_None ? "None" : arg->ob_type->tp_name);
- return msgbuf;
+ assert(expected != NULL);
+ assert(arg != NULL);
+ PyOS_snprintf(msgbuf, bufsize,
+ "must be %.50s, not %.50s", expected,
+ arg == Py_None ? "None" : arg->ob_type->tp_name);
+ return msgbuf;
}
#define CONV_UNICODE "(unicode conversion error)"
@@ -536,14 +534,28 @@
/* explicitly check for float arguments when integers are expected. For now
* signal a warning. Returns true if an exception was raised. */
static int
+float_argument_warning(PyObject *arg)
+{
+ if (PyFloat_Check(arg) &&
+ PyErr_Warn(PyExc_DeprecationWarning,
+ "integer argument expected, got float" ))
+ return 1;
+ else
+ return 0;
+}
+
+/* explicitly check for float arguments when integers are expected. Raises
+ TypeError and returns true for float arguments. */
+static int
float_argument_error(PyObject *arg)
{
- if (PyFloat_Check(arg) &&
- PyErr_Warn(PyExc_DeprecationWarning,
- "integer argument expected, got float" ))
- return 1;
- else
- return 0;
+ if (PyFloat_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float");
+ return 1;
+ }
+ else
+ return 0;
}
/* Convert a non-tuple argument. Return NULL if conversion went OK,
@@ -557,836 +569,839 @@
static char *
convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
- char *msgbuf, size_t bufsize, freelist_t *freelist)
+ char *msgbuf, size_t bufsize, PyObject **freelist)
{
- /* For # codes */
-#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\
- if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \
- else q=va_arg(*p_va, int*);
-#define STORE_SIZE(s) if (flags & FLAG_SIZE_T) *q2=s; else *q=s;
+ /* For # codes */
+#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\
+ if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \
+ else q=va_arg(*p_va, int*);
+#define STORE_SIZE(s) \
+ if (flags & FLAG_SIZE_T) \
+ *q2=s; \
+ else { \
+ if (INT_MAX < s) { \
+ PyErr_SetString(PyExc_OverflowError, \
+ "size does not fit in an int"); \
+ return converterr("", arg, msgbuf, bufsize); \
+ } \
+ *q=s; \
+ }
#define BUFFER_LEN ((flags & FLAG_SIZE_T) ? *q2:*q)
- const char *format = *p_format;
- char c = *format++;
+ const char *format = *p_format;
+ char c = *format++;
#ifdef Py_USING_UNICODE
- PyObject *uarg;
-#endif
-
- switch (c) {
-
- case 'b': { /* unsigned byte -- very short int */
- char *p = va_arg(*p_va, char *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<b>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<b>", arg, msgbuf, bufsize);
- else if (ival < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is less than minimum");
- return converterr("integer<b>", arg, msgbuf, bufsize);
- }
- else if (ival > UCHAR_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is greater than maximum");
- return converterr("integer<b>", arg, msgbuf, bufsize);
- }
- else
- *p = (unsigned char) ival;
- break;
- }
-
- case 'B': {/* byte sized bitfield - both signed and unsigned
- values allowed */
- char *p = va_arg(*p_va, char *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<B>", arg, msgbuf, bufsize);
- ival = PyInt_AsUnsignedLongMask(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<B>", arg, msgbuf, bufsize);
- else
- *p = (unsigned char) ival;
- break;
- }
-
- case 'h': {/* signed short int */
- short *p = va_arg(*p_va, short *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<h>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<h>", arg, msgbuf, bufsize);
- else if (ival < SHRT_MIN) {
- PyErr_SetString(PyExc_OverflowError,
- "signed short integer is less than minimum");
- return converterr("integer<h>", arg, msgbuf, bufsize);
- }
- else if (ival > SHRT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "signed short integer is greater than maximum");
- return converterr("integer<h>", arg, msgbuf, bufsize);
- }
- else
- *p = (short) ival;
- break;
- }
-
- case 'H': { /* short int sized bitfield, both signed and
- unsigned allowed */
- unsigned short *p = va_arg(*p_va, unsigned short *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<H>", arg, msgbuf, bufsize);
- ival = PyInt_AsUnsignedLongMask(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<H>", arg, msgbuf, bufsize);
- else
- *p = (unsigned short) ival;
- break;
- }
- case 'i': {/* signed int */
- int *p = va_arg(*p_va, int *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<i>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<i>", arg, msgbuf, bufsize);
- else if (ival > INT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "signed integer is greater than maximum");
- return converterr("integer<i>", arg, msgbuf, bufsize);
- }
- else if (ival < INT_MIN) {
- PyErr_SetString(PyExc_OverflowError,
- "signed integer is less than minimum");
- return converterr("integer<i>", arg, msgbuf, bufsize);
- }
- else
- *p = ival;
- break;
- }
- case 'I': { /* int sized bitfield, both signed and
- unsigned allowed */
- unsigned int *p = va_arg(*p_va, unsigned int *);
- unsigned int ival;
- if (float_argument_error(arg))
- return converterr("integer<I>", arg, msgbuf, bufsize);
- ival = (unsigned int)PyInt_AsUnsignedLongMask(arg);
- if (ival == (unsigned int)-1 && PyErr_Occurred())
- return converterr("integer<I>", arg, msgbuf, bufsize);
- else
- *p = ival;
- break;
- }
- case 'n': /* Py_ssize_t */
-#if SIZEOF_SIZE_T != SIZEOF_LONG
- {
- Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
- Py_ssize_t ival;
- if (float_argument_error(arg))
- return converterr("integer<n>", arg, msgbuf, bufsize);
- ival = PyInt_AsSsize_t(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<n>", arg, msgbuf, bufsize);
- *p = ival;
- break;
- }
-#endif
- /* Fall through from 'n' to 'l' if Py_ssize_t is int */
- case 'l': {/* long int */
- long *p = va_arg(*p_va, long *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<l>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<l>", arg, msgbuf, bufsize);
- else
- *p = ival;
- break;
- }
-
- case 'k': { /* long sized bitfield */
- unsigned long *p = va_arg(*p_va, unsigned long *);
- unsigned long ival;
- if (PyInt_Check(arg))
- ival = PyInt_AsUnsignedLongMask(arg);
- else if (PyLong_Check(arg))
- ival = PyLong_AsUnsignedLongMask(arg);
- else
- return converterr("integer<k>", arg, msgbuf, bufsize);
- *p = ival;
- break;
- }
-
-#ifdef HAVE_LONG_LONG
- case 'L': {/* PY_LONG_LONG */
- PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
- PY_LONG_LONG ival = PyLong_AsLongLong( arg );
- if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {
- return converterr("long<L>", arg, msgbuf, bufsize);
- } else {
- *p = ival;
- }
- break;
- }
-
- case 'K': { /* long long sized bitfield */
- unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *);
- unsigned PY_LONG_LONG ival;
- if (PyInt_Check(arg))
- ival = PyInt_AsUnsignedLongMask(arg);
- else if (PyLong_Check(arg))
- ival = PyLong_AsUnsignedLongLongMask(arg);
- else
- return converterr("integer<K>", arg, msgbuf, bufsize);
- *p = ival;
- break;
- }
-#endif // HAVE_LONG_LONG
-
- case 'f': {/* float */
- float *p = va_arg(*p_va, float *);
- double dval = PyFloat_AsDouble(arg);
- if (PyErr_Occurred())
- return converterr("float<f>", arg, msgbuf, bufsize);
- else
- *p = (float) dval;
- break;
- }
-
- case 'd': {/* double */
- double *p = va_arg(*p_va, double *);
- double dval = PyFloat_AsDouble(arg);
- if (PyErr_Occurred())
- return converterr("float<d>", arg, msgbuf, bufsize);
- else
- *p = dval;
- break;
- }
-
-#ifndef WITHOUT_COMPLEX
- case 'D': {/* complex double */
- Py_complex *p = va_arg(*p_va, Py_complex *);
- Py_complex cval;
- cval = PyComplex_AsCComplex(arg);
- if (PyErr_Occurred())
- return converterr("complex<D>", arg, msgbuf, bufsize);
- else
- *p = cval;
- break;
- }
-#endif /* WITHOUT_COMPLEX */
-
- case 'c': {/* char */
- char *p = va_arg(*p_va, char *);
- if (PyString_Check(arg) && PyString_Size(arg) == 1)
- *p = PyString_AS_STRING(arg)[0];
- else
- return converterr("char", arg, msgbuf, bufsize);
- break;
- }
- case 's': {/* string */
- if (*format == '*') {
- Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
-
- if (PyString_Check(arg)) {
- fflush(stdout);
- PyBuffer_FillInfo(p, arg,
- PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
- 1, 0);
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
-#if 0
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- PyBuffer_FillInfo(p, arg,
- PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
- 1, 0);
-#else
- return converterr("string or buffer", arg, msgbuf, bufsize);
-#endif
- }
-#endif
- else { /* any buffer-like object */
- char *buf;
- if (getbuffer(arg, p, &buf) < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- }
- if (addcleanup(p, freelist, cleanup_buffer)) {
- return converterr(
- "(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- format++;
- } else if (*format == '#') {
- void **p = (void **)va_arg(*p_va, char **);
- FETCH_SIZE;
-
- if (PyString_Check(arg)) {
- *p = PyString_AS_STRING(arg);
- STORE_SIZE(PyString_GET_SIZE(arg));
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- STORE_SIZE(PyString_GET_SIZE(uarg));
- }
-#endif
- else { /* any buffer-like object */
- char *buf;
- Py_ssize_t count = convertbuffer(arg, p, &buf);
- if (count < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- STORE_SIZE(count);
- }
- format++;
- } else {
- char **p = va_arg(*p_va, char **);
-
- if (PyString_Check(arg))
- *p = PyString_AS_STRING(arg);
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- }
-#endif
- else
- return converterr("string", arg, msgbuf, bufsize);
- if ((Py_ssize_t)strlen(*p) != PyString_Size(arg))
- return converterr("string without null bytes",
- arg, msgbuf, bufsize);
- }
- break;
- }
-
- case 'z': {/* string, may be NULL (None) */
- if (*format == '*') {
- Py_FatalError("'*' format not supported in PyArg_*\n");
-#if 0
- Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
-
- if (arg == Py_None)
- PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
- else if (PyString_Check(arg)) {
- PyBuffer_FillInfo(p, arg,
- PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
- 1, 0);
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- PyBuffer_FillInfo(p, arg,
- PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
- 1, 0);
- }
-#endif
- else { /* any buffer-like object */
- char *buf;
- if (getbuffer(arg, p, &buf) < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- }
- if (addcleanup(p, freelist, cleanup_buffer)) {
- return converterr(
- "(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- format++;
-#endif
- } else if (*format == '#') { /* any buffer-like object */
- void **p = (void **)va_arg(*p_va, char **);
- FETCH_SIZE;
-
- if (arg == Py_None) {
- *p = 0;
- STORE_SIZE(0);
- }
- else if (PyString_Check(arg)) {
- *p = PyString_AS_STRING(arg);
- STORE_SIZE(PyString_GET_SIZE(arg));
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- STORE_SIZE(PyString_GET_SIZE(uarg));
- }
-#endif
- else { /* any buffer-like object */
- char *buf;
- Py_ssize_t count = convertbuffer(arg, p, &buf);
- if (count < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- STORE_SIZE(count);
- }
- format++;
- } else {
- char **p = va_arg(*p_va, char **);
-
- if (arg == Py_None)
- *p = 0;
- else if (PyString_Check(arg))
- *p = PyString_AS_STRING(arg);
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- }
-#endif
- else
- return converterr("string or None",
- arg, msgbuf, bufsize);
- if (*format == '#') {
- FETCH_SIZE;
- assert(0); /* XXX redundant with if-case */
- if (arg == Py_None)
- *q = 0;
- else
- *q = PyString_Size(arg);
- format++;
- }
- else if (*p != NULL &&
- (Py_ssize_t)strlen(*p) != PyString_Size(arg))
- return converterr(
- "string without null bytes or None",
- arg, msgbuf, bufsize);
- }
- break;
- }
- case 'e': {/* encoded string */
- char **buffer;
- const char *encoding;
- PyObject *s;
- Py_ssize_t size;
- int recode_strings;
-
- /* Get 'e' parameter: the encoding name */
- encoding = (const char *)va_arg(*p_va, const char *);
-#ifdef Py_USING_UNICODE
- if (encoding == NULL)
- encoding = PyUnicode_GetDefaultEncoding();
+ PyObject *uarg;
#endif
- /* Get output buffer parameter:
- 's' (recode all objects via Unicode) or
- 't' (only recode non-string objects)
- */
- if (*format == 's')
- recode_strings = 1;
- else if (*format == 't')
- recode_strings = 0;
- else
- return converterr(
- "(unknown parser marker combination)",
- arg, msgbuf, bufsize);
- buffer = (char **)va_arg(*p_va, char **);
- format++;
- if (buffer == NULL)
- return converterr("(buffer is NULL)",
- arg, msgbuf, bufsize);
-
- /* Encode object */
- if (!recode_strings && PyString_Check(arg)) {
- s = arg;
- Py_INCREF(s);
- }
- else {
+ switch (c) {
+
+ case 'b': { /* unsigned byte -- very short int */
+ char *p = va_arg(*p_va, char *);
+ long ival;
+ if (float_argument_error(arg))
+ return converterr("integer<b>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<b>", arg, msgbuf, bufsize);
+ else if (ival < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned byte integer is less than minimum");
+ return converterr("integer<b>", arg, msgbuf, bufsize);
+ }
+ else if (ival > UCHAR_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned byte integer is greater than maximum");
+ return converterr("integer<b>", arg, msgbuf, bufsize);
+ }
+ else
+ *p = (unsigned char) ival;
+ break;
+ }
+
+ case 'B': {/* byte sized bitfield - both signed and unsigned
+ values allowed */
+ char *p = va_arg(*p_va, char *);
+ long ival;
+ if (float_argument_error(arg))
+ return converterr("integer<B>", arg, msgbuf, bufsize);
+ ival = PyInt_AsUnsignedLongMask(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<B>", arg, msgbuf, bufsize);
+ else
+ *p = (unsigned char) ival;
+ break;
+ }
+
+ case 'h': {/* signed short int */
+ short *p = va_arg(*p_va, short *);
+ long ival;
+ if (float_argument_error(arg))
+ return converterr("integer<h>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<h>", arg, msgbuf, bufsize);
+ else if (ival < SHRT_MIN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed short integer is less than minimum");
+ return converterr("integer<h>", arg, msgbuf, bufsize);
+ }
+ else if (ival > SHRT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed short integer is greater than maximum");
+ return converterr("integer<h>", arg, msgbuf, bufsize);
+ }
+ else
+ *p = (short) ival;
+ break;
+ }
+
+ case 'H': { /* short int sized bitfield, both signed and
+ unsigned allowed */
+ unsigned short *p = va_arg(*p_va, unsigned short *);
+ long ival;
+ if (float_argument_error(arg))
+ return converterr("integer<H>", arg, msgbuf, bufsize);
+ ival = PyInt_AsUnsignedLongMask(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<H>", arg, msgbuf, bufsize);
+ else
+ *p = (unsigned short) ival;
+ break;
+ }
+
+ case 'i': {/* signed int */
+ int *p = va_arg(*p_va, int *);
+ long ival;
+ if (float_argument_error(arg))
+ return converterr("integer<i>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<i>", arg, msgbuf, bufsize);
+ else if (ival > INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed integer is greater than maximum");
+ return converterr("integer<i>", arg, msgbuf, bufsize);
+ }
+ else if (ival < INT_MIN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed integer is less than minimum");
+ return converterr("integer<i>", arg, msgbuf, bufsize);
+ }
+ else
+ *p = ival;
+ break;
+ }
+
+ case 'I': { /* int sized bitfield, both signed and
+ unsigned allowed */
+ unsigned int *p = va_arg(*p_va, unsigned int *);
+ unsigned int ival;
+ if (float_argument_error(arg))
+ return converterr("integer<I>", arg, msgbuf, bufsize);
+ ival = (unsigned int)PyInt_AsUnsignedLongMask(arg);
+ if (ival == (unsigned int)-1 && PyErr_Occurred())
+ return converterr("integer<I>", arg, msgbuf, bufsize);
+ else
+ *p = ival;
+ break;
+ }
+
+ case 'n': /* Py_ssize_t */
+#if SIZEOF_SIZE_T != SIZEOF_LONG
+ {
+ Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
+ Py_ssize_t ival;
+ if (float_argument_error(arg))
+ return converterr("integer<n>", arg, msgbuf, bufsize);
+ ival = PyInt_AsSsize_t(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<n>", arg, msgbuf, bufsize);
+ *p = ival;
+ break;
+ }
+#endif
+ /* Fall through from 'n' to 'l' if Py_ssize_t is int */
+ case 'l': {/* long int */
+ long *p = va_arg(*p_va, long *);
+ long ival;
+ if (float_argument_error(arg))
+ return converterr("integer<l>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<l>", arg, msgbuf, bufsize);
+ else
+ *p = ival;
+ break;
+ }
+
+ case 'k': { /* long sized bitfield */
+ unsigned long *p = va_arg(*p_va, unsigned long *);
+ unsigned long ival;
+ if (PyInt_Check(arg))
+ ival = PyInt_AsUnsignedLongMask(arg);
+ else if (PyLong_Check(arg))
+ ival = PyLong_AsUnsignedLongMask(arg);
+ else
+ return converterr("integer<k>", arg, msgbuf, bufsize);
+ *p = ival;
+ break;
+ }
+
+#ifdef HAVE_LONG_LONG
+ case 'L': {/* PY_LONG_LONG */
+ PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
+ PY_LONG_LONG ival;
+ if (float_argument_warning(arg))
+ return converterr("long<L>", arg, msgbuf, bufsize);
+ ival = PyLong_AsLongLong(arg);
+ if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {
+ return converterr("long<L>", arg, msgbuf, bufsize);
+ } else {
+ *p = ival;
+ }
+ break;
+ }
+
+ case 'K': { /* long long sized bitfield */
+ unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *);
+ unsigned PY_LONG_LONG ival;
+ if (PyInt_Check(arg))
+ ival = PyInt_AsUnsignedLongMask(arg);
+ else if (PyLong_Check(arg))
+ ival = PyLong_AsUnsignedLongLongMask(arg);
+ else
+ return converterr("integer<K>", arg, msgbuf, bufsize);
+ *p = ival;
+ break;
+ }
+#endif
+
+ case 'f': {/* float */
+ float *p = va_arg(*p_va, float *);
+ double dval = PyFloat_AsDouble(arg);
+ if (PyErr_Occurred())
+ return converterr("float<f>", arg, msgbuf, bufsize);
+ else
+ *p = (float) dval;
+ break;
+ }
+
+ case 'd': {/* double */
+ double *p = va_arg(*p_va, double *);
+ double dval = PyFloat_AsDouble(arg);
+ if (PyErr_Occurred())
+ return converterr("float<d>", arg, msgbuf, bufsize);
+ else
+ *p = dval;
+ break;
+ }
+
+#ifndef WITHOUT_COMPLEX
+ case 'D': {/* complex double */
+ Py_complex *p = va_arg(*p_va, Py_complex *);
+ Py_complex cval;
+ cval = PyComplex_AsCComplex(arg);
+ if (PyErr_Occurred())
+ return converterr("complex<D>", arg, msgbuf, bufsize);
+ else
+ *p = cval;
+ break;
+ }
+#endif /* WITHOUT_COMPLEX */
+
+ case 'c': {/* char */
+ char *p = va_arg(*p_va, char *);
+ if (PyString_Check(arg) && PyString_Size(arg) == 1)
+ *p = PyString_AS_STRING(arg)[0];
+ else
+ return converterr("char", arg, msgbuf, bufsize);
+ break;
+ }
+
+ case 's': {/* string */
+ if (*format == '*') {
+ Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
+
+ if (PyString_Check(arg)) {
+ PyBuffer_FillInfo(p, arg,
+ PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
+ 1, 0);
+ }
#ifdef Py_USING_UNICODE
- PyObject *u;
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ PyBuffer_FillInfo(p, arg,
+ PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
+ 1, 0);
+ }
+#endif
+ else { /* any buffer-like object */
+ char *buf;
+ if (getbuffer(arg, p, &buf) < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ }
+ if (addcleanup(p, freelist, cleanup_buffer)) {
+ return converterr(
+ "(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ format++;
+ } else if (*format == '#') {
+ void **p = (void **)va_arg(*p_va, char **);
+ FETCH_SIZE;
- /* Convert object to Unicode */
- u = PyUnicode_FromObject(arg);
- if (u == NULL)
- return converterr(
- "string or unicode or text buffer",
- arg, msgbuf, bufsize);
-
- /* Encode object; use default error handling */
- s = PyUnicode_AsEncodedString(u,
- encoding,
- NULL);
- Py_DECREF(u);
- if (s == NULL)
- return converterr("(encoding failed)",
- arg, msgbuf, bufsize);
- if (!PyString_Check(s)) {
- Py_DECREF(s);
- return converterr(
- "(encoder failed to return a string)",
- arg, msgbuf, bufsize);
- }
+ if (PyString_Check(arg)) {
+ *p = PyString_AS_STRING(arg);
+ STORE_SIZE(PyString_GET_SIZE(arg));
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ *p = PyString_AS_STRING(uarg);
+ STORE_SIZE(PyString_GET_SIZE(uarg));
+ }
+#endif
+ else { /* any buffer-like object */
+ char *buf;
+ Py_ssize_t count = convertbuffer(arg, p, &buf);
+ if (count < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ STORE_SIZE(count);
+ }
+ format++;
+ } else {
+ char **p = va_arg(*p_va, char **);
+
+ if (PyString_Check(arg))
+ *p = PyString_AS_STRING(arg);
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ *p = PyString_AS_STRING(uarg);
+ }
+#endif
+ else
+ return converterr("string", arg, msgbuf, bufsize);
+ if ((Py_ssize_t)strlen(*p) != PyString_Size(arg))
+ return converterr("string without null bytes",
+ arg, msgbuf, bufsize);
+ }
+ break;
+ }
+
+ case 'z': {/* string, may be NULL (None) */
+ if (*format == '*') {
+ Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
+
+ if (arg == Py_None)
+ PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
+ else if (PyString_Check(arg)) {
+ PyBuffer_FillInfo(p, arg,
+ PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
+ 1, 0);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ PyBuffer_FillInfo(p, arg,
+ PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
+ 1, 0);
+ }
+#endif
+ else { /* any buffer-like object */
+ char *buf;
+ if (getbuffer(arg, p, &buf) < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ }
+ if (addcleanup(p, freelist, cleanup_buffer)) {
+ return converterr(
+ "(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ format++;
+ } else if (*format == '#') { /* any buffer-like object */
+ void **p = (void **)va_arg(*p_va, char **);
+ FETCH_SIZE;
+
+ if (arg == Py_None) {
+ *p = 0;
+ STORE_SIZE(0);
+ }
+ else if (PyString_Check(arg)) {
+ *p = PyString_AS_STRING(arg);
+ STORE_SIZE(PyString_GET_SIZE(arg));
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ *p = PyString_AS_STRING(uarg);
+ STORE_SIZE(PyString_GET_SIZE(uarg));
+ }
+#endif
+ else { /* any buffer-like object */
+ char *buf;
+ Py_ssize_t count = convertbuffer(arg, p, &buf);
+ if (count < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ STORE_SIZE(count);
+ }
+ format++;
+ } else {
+ char **p = va_arg(*p_va, char **);
+
+ if (arg == Py_None)
+ *p = 0;
+ else if (PyString_Check(arg))
+ *p = PyString_AS_STRING(arg);
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ *p = PyString_AS_STRING(uarg);
+ }
+#endif
+ else
+ return converterr("string or None",
+ arg, msgbuf, bufsize);
+ if (*format == '#') {
+ FETCH_SIZE;
+ assert(0); /* XXX redundant with if-case */
+ if (arg == Py_None) {
+ STORE_SIZE(0);
+ } else {
+ STORE_SIZE(PyString_Size(arg));
+ }
+ format++;
+ }
+ else if (*p != NULL &&
+ (Py_ssize_t)strlen(*p) != PyString_Size(arg))
+ return converterr(
+ "string without null bytes or None",
+ arg, msgbuf, bufsize);
+ }
+ break;
+ }
+
+ case 'e': {/* encoded string */
+ char **buffer;
+ const char *encoding;
+ PyObject *s;
+ Py_ssize_t size;
+ int recode_strings;
+
+ /* Get 'e' parameter: the encoding name */
+ encoding = (const char *)va_arg(*p_va, const char *);
+#ifdef Py_USING_UNICODE
+ if (encoding == NULL)
+ encoding = PyUnicode_GetDefaultEncoding();
+#endif
+
+ /* Get output buffer parameter:
+ 's' (recode all objects via Unicode) or
+ 't' (only recode non-string objects)
+ */
+ if (*format == 's')
+ recode_strings = 1;
+ else if (*format == 't')
+ recode_strings = 0;
+ else
+ return converterr(
+ "(unknown parser marker combination)",
+ arg, msgbuf, bufsize);
+ buffer = (char **)va_arg(*p_va, char **);
+ format++;
+ if (buffer == NULL)
+ return converterr("(buffer is NULL)",
+ arg, msgbuf, bufsize);
+
+ /* Encode object */
+ if (!recode_strings && PyString_Check(arg)) {
+ s = arg;
+ Py_INCREF(s);
+ }
+ else {
+#ifdef Py_USING_UNICODE
+ PyObject *u;
+
+ /* Convert object to Unicode */
+ u = PyUnicode_FromObject(arg);
+ if (u == NULL)
+ return converterr(
+ "string or unicode or text buffer",
+ arg, msgbuf, bufsize);
+
+ /* Encode object; use default error handling */
+ s = PyUnicode_AsEncodedString(u,
+ encoding,
+ NULL);
+ Py_DECREF(u);
+ if (s == NULL)
+ return converterr("(encoding failed)",
+ arg, msgbuf, bufsize);
+ if (!PyString_Check(s)) {
+ Py_DECREF(s);
+ return converterr(
+ "(encoder failed to return a string)",
+ arg, msgbuf, bufsize);
+ }
#else
- return converterr("string<e>", arg, msgbuf, bufsize);
+ return converterr("string<e>", arg, msgbuf, bufsize);
#endif
- }
- size = PyString_GET_SIZE(s);
+ }
+ size = PyString_GET_SIZE(s);
- /* Write output; output is guaranteed to be 0-terminated */
- if (*format == '#') {
- /* Using buffer length parameter '#':
-
- - if *buffer is NULL, a new buffer of the
- needed size is allocated and the data
- copied into it; *buffer is updated to point
- to the new buffer; the caller is
- responsible for PyMem_Free()ing it after
- usage
+ /* Write output; output is guaranteed to be 0-terminated */
+ if (*format == '#') {
+ /* Using buffer length parameter '#':
- - if *buffer is not NULL, the data is
- copied to *buffer; *buffer_len has to be
- set to the size of the buffer on input;
- buffer overflow is signalled with an error;
- buffer has to provide enough room for the
- encoded string plus the trailing 0-byte
-
- - in both cases, *buffer_len is updated to
- the size of the buffer /excluding/ the
- trailing 0-byte
-
- */
- FETCH_SIZE;
+ - if *buffer is NULL, a new buffer of the
+ needed size is allocated and the data
+ copied into it; *buffer is updated to point
+ to the new buffer; the caller is
+ responsible for PyMem_Free()ing it after
+ usage
- format++;
- if (q == NULL && q2 == NULL) {
- Py_DECREF(s);
- return converterr(
- "(buffer_len is NULL)",
- arg, msgbuf, bufsize);
- }
- if (*buffer == NULL) {
- *buffer = PyMem_NEW(char, size + 1);
- if (*buffer == NULL) {
- Py_DECREF(s);
- return converterr(
- "(memory error)",
- arg, msgbuf, bufsize);
- }
- if (addcleanup(*buffer, freelist, cleanup_ptr)) {
- Py_DECREF(s);
- return converterr(
- "(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- } else {
- if (size + 1 > BUFFER_LEN) {
- Py_DECREF(s);
- return converterr(
- "(buffer overflow)",
- arg, msgbuf, bufsize);
- }
- }
- memcpy(*buffer,
- PyString_AS_STRING(s),
- size + 1);
- STORE_SIZE(size);
- } else {
- /* Using a 0-terminated buffer:
-
- - the encoded string has to be 0-terminated
- for this variant to work; if it is not, an
- error raised
+ - if *buffer is not NULL, the data is
+ copied to *buffer; *buffer_len has to be
+ set to the size of the buffer on input;
+ buffer overflow is signalled with an error;
+ buffer has to provide enough room for the
+ encoded string plus the trailing 0-byte
- - a new buffer of the needed size is
- allocated and the data copied into it;
- *buffer is updated to point to the new
- buffer; the caller is responsible for
- PyMem_Free()ing it after usage
+ - in both cases, *buffer_len is updated to
+ the size of the buffer /excluding/ the
+ trailing 0-byte
- */
- if ((Py_ssize_t)strlen(PyString_AS_STRING(s))
- != size) {
- Py_DECREF(s);
- return converterr(
- "encoded string without NULL bytes",
- arg, msgbuf, bufsize);
- }
- *buffer = PyMem_NEW(char, size + 1);
- if (*buffer == NULL) {
- Py_DECREF(s);
- return converterr("(memory error)",
- arg, msgbuf, bufsize);
- }
- if (addcleanup(*buffer, freelist, cleanup_ptr)) {
- Py_DECREF(s);
- return converterr("(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- memcpy(*buffer,
- PyString_AS_STRING(s),
- size + 1);
- }
- Py_DECREF(s);
- break;
- }
+ */
+ FETCH_SIZE;
+
+ format++;
+ if (q == NULL && q2 == NULL) {
+ Py_DECREF(s);
+ return converterr(
+ "(buffer_len is NULL)",
+ arg, msgbuf, bufsize);
+ }
+ if (*buffer == NULL) {
+ *buffer = PyMem_NEW(char, size + 1);
+ if (*buffer == NULL) {
+ Py_DECREF(s);
+ return converterr(
+ "(memory error)",
+ arg, msgbuf, bufsize);
+ }
+ if (addcleanup(*buffer, freelist, cleanup_ptr)) {
+ Py_DECREF(s);
+ return converterr(
+ "(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ } else {
+ if (size + 1 > BUFFER_LEN) {
+ Py_DECREF(s);
+ return converterr(
+ "(buffer overflow)",
+ arg, msgbuf, bufsize);
+ }
+ }
+ memcpy(*buffer,
+ PyString_AS_STRING(s),
+ size + 1);
+ STORE_SIZE(size);
+ } else {
+ /* Using a 0-terminated buffer:
+
+ - the encoded string has to be 0-terminated
+ for this variant to work; if it is not, an
+ error raised
+
+ - a new buffer of the needed size is
+ allocated and the data copied into it;
+ *buffer is updated to point to the new
+ buffer; the caller is responsible for
+ PyMem_Free()ing it after usage
+
+ */
+ if ((Py_ssize_t)strlen(PyString_AS_STRING(s))
+ != size) {
+ Py_DECREF(s);
+ return converterr(
+ "encoded string without NULL bytes",
+ arg, msgbuf, bufsize);
+ }
+ *buffer = PyMem_NEW(char, size + 1);
+ if (*buffer == NULL) {
+ Py_DECREF(s);
+ return converterr("(memory error)",
+ arg, msgbuf, bufsize);
+ }
+ if (addcleanup(*buffer, freelist, cleanup_ptr)) {
+ Py_DECREF(s);
+ return converterr("(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ memcpy(*buffer,
+ PyString_AS_STRING(s),
+ size + 1);
+ }
+ Py_DECREF(s);
+ break;
+ }
#ifdef Py_USING_UNICODE
- case 'u': {/* raw unicode buffer (Py_UNICODE *) */
- if (*format == '#') { /* any buffer-like object */
- void **p = (void **)va_arg(*p_va, char **);
- FETCH_SIZE;
- if (PyUnicode_Check(arg)) {
- *p = PyUnicode_AS_UNICODE(arg);
- STORE_SIZE(PyUnicode_GET_SIZE(arg));
- }
- else {
- return converterr("cannot convert raw buffers",
- arg, msgbuf, bufsize);
- }
- format++;
- } else {
- Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
- if (PyUnicode_Check(arg))
- *p = PyUnicode_AS_UNICODE(arg);
- else
- return converterr("unicode", arg, msgbuf, bufsize);
- }
- break;
- }
+ case 'u': {/* raw unicode buffer (Py_UNICODE *) */
+ if (*format == '#') { /* any buffer-like object */
+ void **p = (void **)va_arg(*p_va, char **);
+ FETCH_SIZE;
+ if (PyUnicode_Check(arg)) {
+ *p = PyUnicode_AS_UNICODE(arg);
+ STORE_SIZE(PyUnicode_GET_SIZE(arg));
+ }
+ else {
+ return converterr("cannot convert raw buffers",
+ arg, msgbuf, bufsize);
+ }
+ format++;
+ } else {
+ Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
+ if (PyUnicode_Check(arg))
+ *p = PyUnicode_AS_UNICODE(arg);
+ else
+ return converterr("unicode", arg, msgbuf, bufsize);
+ }
+ break;
+ }
#endif
- case 'S': { /* string object */
- PyObject **p = va_arg(*p_va, PyObject **);
- if (PyString_Check(arg))
- *p = arg;
- else
- return converterr("string", arg, msgbuf, bufsize);
- break;
- }
-
+ case 'S': { /* string object */
+ PyObject **p = va_arg(*p_va, PyObject **);
+ if (PyString_Check(arg))
+ *p = arg;
+ else
+ return converterr("string", arg, msgbuf, bufsize);
+ break;
+ }
+
#ifdef Py_USING_UNICODE
- case 'U': { /* Unicode object */
- PyObject **p = va_arg(*p_va, PyObject **);
- if (PyUnicode_Check(arg))
- *p = arg;
- else
- return converterr("unicode", arg, msgbuf, bufsize);
- break;
- }
+ case 'U': { /* Unicode object */
+ PyObject **p = va_arg(*p_va, PyObject **);
+ if (PyUnicode_Check(arg))
+ *p = arg;
+ else
+ return converterr("unicode", arg, msgbuf, bufsize);
+ break;
+ }
#endif
- case 'O': { /* object */
- PyTypeObject *type;
- PyObject **p;
- if (*format == '!') {
- type = va_arg(*p_va, PyTypeObject*);
- p = va_arg(*p_va, PyObject **);
- format++;
- if (PyType_IsSubtype(arg->ob_type, type))
- *p = arg;
- else
- return converterr(type->tp_name, arg, msgbuf, bufsize);
- }
- else if (*format == '?') {
- inquiry pred = va_arg(*p_va, inquiry);
- p = va_arg(*p_va, PyObject **);
- format++;
- if ((*pred)(arg))
- *p = arg;
- else
- return converterr("(unspecified)",
- arg, msgbuf, bufsize);
-
- }
- else if (*format == '&') {
- typedef int (*converter)(PyObject *, void *);
- converter convert = va_arg(*p_va, converter);
- void *addr = va_arg(*p_va, void *);
- format++;
- if (! (*convert)(arg, addr))
- return converterr("(unspecified)",
- arg, msgbuf, bufsize);
- }
- else {
- p = va_arg(*p_va, PyObject **);
- *p = arg;
- }
- break;
- }
-
- case 'w': { /* memory buffer, read-write access */
- Py_FatalError("'w' unsupported\n");
-#if 0
- void **p = va_arg(*p_va, void **);
- void *res;
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- Py_ssize_t count;
+ case 'O': { /* object */
+ PyTypeObject *type;
+ PyObject **p;
+ if (*format == '!') {
+ type = va_arg(*p_va, PyTypeObject*);
+ p = va_arg(*p_va, PyObject **);
+ format++;
+ if (PyType_IsSubtype(arg->ob_type, type))
+ *p = arg;
+ else
+ return converterr(type->tp_name, arg, msgbuf, bufsize);
- if (pb && pb->bf_releasebuffer && *format != '*')
- /* Buffer must be released, yet caller does not use
- the Py_buffer protocol. */
- return converterr("pinned buffer", arg, msgbuf, bufsize);
+ }
+ else if (*format == '?') {
+ inquiry pred = va_arg(*p_va, inquiry);
+ p = va_arg(*p_va, PyObject **);
+ format++;
+ if ((*pred)(arg))
+ *p = arg;
+ else
+ return converterr("(unspecified)",
+ arg, msgbuf, bufsize);
- if (pb && pb->bf_getbuffer && *format == '*') {
- /* Caller is interested in Py_buffer, and the object
- supports it directly. */
- format++;
- if (pb->bf_getbuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
- PyErr_Clear();
- return converterr("read-write buffer", arg, msgbuf, bufsize);
- }
- if (addcleanup(p, freelist, cleanup_buffer)) {
- return converterr(
- "(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C'))
- return converterr("contiguous buffer", arg, msgbuf, bufsize);
- break;
- }
+ }
+ else if (*format == '&') {
+ typedef int (*converter)(PyObject *, void *);
+ converter convert = va_arg(*p_va, converter);
+ void *addr = va_arg(*p_va, void *);
+ format++;
+ if (! (*convert)(arg, addr))
+ return converterr("(unspecified)",
+ arg, msgbuf, bufsize);
+ }
+ else {
+ p = va_arg(*p_va, PyObject **);
+ *p = arg;
+ }
+ break;
+ }
- if (pb == NULL ||
- pb->bf_getwritebuffer == NULL ||
- pb->bf_getsegcount == NULL)
- return converterr("read-write buffer", arg, msgbuf, bufsize);
- if ((*pb->bf_getsegcount)(arg, NULL) != 1)
- return converterr("single-segment read-write buffer",
- arg, msgbuf, bufsize);
- if ((count = pb->bf_getwritebuffer(arg, 0, &res)) < 0)
- return converterr("(unspecified)", arg, msgbuf, bufsize);
- if (*format == '*') {
- PyBuffer_FillInfo((Py_buffer*)p, arg, res, count, 1, 0);
- format++;
- }
- else {
- *p = res;
- if (*format == '#') {
- FETCH_SIZE;
- STORE_SIZE(count);
- format++;
- }
- }
- break;
-#endif
- }
-
- case 't': { /* 8-bit character buffer, read-only access */
- char **p = va_arg(*p_va, char **);
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- Py_ssize_t count;
-#if 0
- if (*format++ != '#')
- return converterr(
- "invalid use of 't' format character",
- arg, msgbuf, bufsize);
-#endif
- if (!PyType_HasFeature(arg->ob_type,
- Py_TPFLAGS_HAVE_GETCHARBUFFER)
-#if 0
- || pb == NULL || pb->bf_getcharbuffer == NULL ||
- pb->bf_getsegcount == NULL
-#endif
- )
- return converterr(
- "string or read-only character buffer",
- arg, msgbuf, bufsize);
-#if 0
- if (pb->bf_getsegcount(arg, NULL) != 1)
- return converterr(
- "string or single-segment read-only buffer",
- arg, msgbuf, bufsize);
+ case 'w': { /* memory buffer, read-write access */
+ void **p = va_arg(*p_va, void **);
+ void *res;
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ Py_ssize_t count;
- if (pb->bf_releasebuffer)
- return converterr(
- "string or pinned buffer",
- arg, msgbuf, bufsize);
-#endif
- count = pb->bf_getcharbuffer(arg, 0, p);
-#if 0
- if (count < 0)
- return converterr("(unspecified)", arg, msgbuf, bufsize);
-#endif
- {
- FETCH_SIZE;
- STORE_SIZE(count);
- ++format;
- }
- break;
- }
- default:
- return converterr("impossible<bad format char>", arg, msgbuf, bufsize);
-
- }
-
- *p_format = format;
- return NULL;
+ if (pb && pb->bf_releasebuffer && *format != '*')
+ /* Buffer must be released, yet caller does not use
+ the Py_buffer protocol. */
+ return converterr("pinned buffer", arg, msgbuf, bufsize);
+
+ if (pb && pb->bf_getbuffer && *format == '*') {
+ /* Caller is interested in Py_buffer, and the object
+ supports it directly. */
+ format++;
+ if (pb->bf_getbuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
+ PyErr_Clear();
+ return converterr("read-write buffer", arg, msgbuf, bufsize);
+ }
+ if (addcleanup(p, freelist, cleanup_buffer)) {
+ return converterr(
+ "(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C'))
+ return converterr("contiguous buffer", arg, msgbuf, bufsize);
+ break;
+ }
+
+ if (pb == NULL ||
+ pb->bf_getwritebuffer == NULL ||
+ pb->bf_getsegcount == NULL)
+ return converterr("read-write buffer", arg, msgbuf, bufsize);
+ if ((*pb->bf_getsegcount)(arg, NULL) != 1)
+ return converterr("single-segment read-write buffer",
+ arg, msgbuf, bufsize);
+ if ((count = pb->bf_getwritebuffer(arg, 0, &res)) < 0)
+ return converterr("(unspecified)", arg, msgbuf, bufsize);
+ if (*format == '*') {
+ PyBuffer_FillInfo((Py_buffer*)p, arg, res, count, 1, 0);
+ format++;
+ }
+ else {
+ *p = res;
+ if (*format == '#') {
+ FETCH_SIZE;
+ STORE_SIZE(count);
+ format++;
+ }
+ }
+ break;
+ }
+
+ case 't': { /* 8-bit character buffer, read-only access */
+ char **p = va_arg(*p_va, char **);
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ Py_ssize_t count;
+
+ if (*format++ != '#')
+ return converterr(
+ "invalid use of 't' format character",
+ arg, msgbuf, bufsize);
+ if (!PyType_HasFeature(arg->ob_type,
+ Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
+ pb == NULL || pb->bf_getcharbuffer == NULL ||
+ pb->bf_getsegcount == NULL)
+ return converterr(
+ "string or read-only character buffer",
+ arg, msgbuf, bufsize);
+
+ if (pb->bf_getsegcount(arg, NULL) != 1)
+ return converterr(
+ "string or single-segment read-only buffer",
+ arg, msgbuf, bufsize);
+
+ if (pb->bf_releasebuffer)
+ return converterr(
+ "string or pinned buffer",
+ arg, msgbuf, bufsize);
+
+ count = pb->bf_getcharbuffer(arg, 0, p);
+ if (count < 0)
+ return converterr("(unspecified)", arg, msgbuf, bufsize);
+ {
+ FETCH_SIZE;
+ STORE_SIZE(count);
+ }
+ break;
+ }
+
+ default:
+ return converterr("impossible<bad format char>", arg, msgbuf, bufsize);
+
+ }
+
+ *p_format = format;
+ return NULL;
}
static Py_ssize_t
convertbuffer(PyObject *arg, void **p, char **errmsg)
{
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- Py_ssize_t count;
- if (pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL ||
- pb->bf_releasebuffer != NULL) {
- *errmsg = "string or read-only buffer";
- return -1;
- }
- if ((*pb->bf_getsegcount)(arg, NULL) != 1) {
- *errmsg = "string or single-segment read-only buffer";
- return -1;
- }
- if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) {
- *errmsg = "(unspecified)";
- }
- return count;
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ Py_ssize_t count;
+ if (pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL ||
+ pb->bf_releasebuffer != NULL) {
+ *errmsg = "string or read-only buffer";
+ return -1;
+ }
+ if ((*pb->bf_getsegcount)(arg, NULL) != 1) {
+ *errmsg = "string or single-segment read-only buffer";
+ return -1;
+ }
+ if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) {
+ *errmsg = "(unspecified)";
+ }
+ return count;
}
static int
getbuffer(PyObject *arg, Py_buffer *view, char **errmsg)
{
- void *buf;
- Py_ssize_t count;
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- if (pb == NULL) {
- *errmsg = "string or buffer";
- return -1;
- }
- if (pb->bf_getbuffer) {
- if (pb->bf_getbuffer(arg, view, 0) < 0) {
- *errmsg = "convertible to a buffer";
- return -1;
- }
- if (!PyBuffer_IsContiguous(view, 'C')) {
- *errmsg = "contiguous buffer";
- return -1;
- }
- return 0;
- }
+ void *buf;
+ Py_ssize_t count;
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ if (pb == NULL) {
+ *errmsg = "string or buffer";
+ return -1;
+ }
+ if (pb->bf_getbuffer) {
+ if (pb->bf_getbuffer(arg, view, 0) < 0) {
+ *errmsg = "convertible to a buffer";
+ return -1;
+ }
+ if (!PyBuffer_IsContiguous(view, 'C')) {
+ *errmsg = "contiguous buffer";
+ return -1;
+ }
+ return 0;
+ }
- count = convertbuffer(arg, &buf, errmsg);
- if (count < 0) {
- *errmsg = "convertible to a buffer";
- return count;
- }
- PyBuffer_FillInfo(view, NULL, buf, count, 1, 0);
- return 0;
+ count = convertbuffer(arg, &buf, errmsg);
+ if (count < 0) {
+ *errmsg = "convertible to a buffer";
+ return count;
+ }
+ PyBuffer_FillInfo(view, arg, buf, count, 1, 0);
+ return 0;
}
/* Support for keyword arguments donated by
@@ -1395,501 +1410,487 @@
/* Return false (0) for error, else true. */
int
PyArg_ParseTupleAndKeywords(PyObject *args,
- PyObject *keywords,
- const char *format,
- char **kwlist, ...)
+ PyObject *keywords,
+ const char *format,
+ char **kwlist, ...)
{
- int retval;
- va_list va;
+ int retval;
+ va_list va;
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
- va_start(va, kwlist);
- retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
- va_end(va);
- return retval;
+ va_start(va, kwlist);
+ retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
+ va_end(va);
+ return retval;
}
int
_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
- PyObject *keywords,
- const char *format,
- char **kwlist, ...)
+ PyObject *keywords,
+ const char *format,
+ char **kwlist, ...)
{
- int retval;
- va_list va;
+ int retval;
+ va_list va;
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
- va_start(va, kwlist);
- retval = vgetargskeywords(args, keywords, format,
- kwlist, &va, FLAG_SIZE_T);
- va_end(va);
- return retval;
+ va_start(va, kwlist);
+ retval = vgetargskeywords(args, keywords, format,
+ kwlist, &va, FLAG_SIZE_T);
+ va_end(va);
+ return retval;
}
int
PyArg_VaParseTupleAndKeywords(PyObject *args,
PyObject *keywords,
- const char *format,
+ const char *format,
char **kwlist, va_list va)
{
- int retval;
- va_list lva;
+ int retval;
+ va_list lva;
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
+ memcpy(lva, va, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(lva, va);
+ __va_copy(lva, va);
#else
- lva = va;
+ lva = va;
#endif
#endif
- retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
- return retval;
+ retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
+ return retval;
}
int
_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
- PyObject *keywords,
- const char *format,
- char **kwlist, va_list va)
+ PyObject *keywords,
+ const char *format,
+ char **kwlist, va_list va)
{
- int retval;
- va_list lva;
+ int retval;
+ va_list lva;
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
+ memcpy(lva, va, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(lva, va);
+ __va_copy(lva, va);
#else
- lva = va;
+ lva = va;
#endif
#endif
- retval = vgetargskeywords(args, keywords, format,
- kwlist, &lva, FLAG_SIZE_T);
- return retval;
+ retval = vgetargskeywords(args, keywords, format,
+ kwlist, &lva, FLAG_SIZE_T);
+ return retval;
}
#define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
static int
vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
- char **kwlist, va_list *p_va, int flags)
+ char **kwlist, va_list *p_va, int flags)
{
- char msgbuf[512];
- int levels[32];
- const char *fname, *msg, *custom_msg, *keyword;
- int min = INT_MAX;
- int i, len, nargs, nkeywords;
- PyObject *current_arg;
- freelist_t freelist = {0, NULL};
+ char msgbuf[512];
+ int levels[32];
+ const char *fname, *msg, *custom_msg, *keyword;
+ int min = INT_MAX;
+ int i, len, nargs, nkeywords;
+ PyObject *freelist = NULL, *current_arg;
+ assert(args != NULL && PyTuple_Check(args));
+ assert(keywords == NULL || PyDict_Check(keywords));
+ assert(format != NULL);
+ assert(kwlist != NULL);
+ assert(p_va != NULL);
- assert(args != NULL && PyTuple_Check(args));
- assert(keywords == NULL || PyDict_Check(keywords));
- assert(format != NULL);
- assert(kwlist != NULL);
- assert(p_va != NULL);
+ /* grab the function name or custom error msg first (mutually exclusive) */
+ fname = strchr(format, ':');
+ if (fname) {
+ fname++;
+ custom_msg = NULL;
+ }
+ else {
+ custom_msg = strchr(format,';');
+ if (custom_msg)
+ custom_msg++;
+ }
- /* grab the function name or custom error msg first (mutually exclusive) */
- fname = strchr(format, ':');
- if (fname) {
- fname++;
- custom_msg = NULL;
- }
- else {
- custom_msg = strchr(format,';');
- if (custom_msg)
- custom_msg++;
- }
+ /* scan kwlist and get greatest possible nbr of args */
+ for (len=0; kwlist[len]; len++)
+ continue;
- /* scan kwlist and get greatest possible nbr of args */
- for (len=0; kwlist[len]; len++)
- continue;
+ nargs = PyTuple_GET_SIZE(args);
+ nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords);
+ if (nargs + nkeywords > len) {
+ PyErr_Format(PyExc_TypeError, "%s%s takes at most %d "
+ "argument%s (%d given)",
+ (fname == NULL) ? "function" : fname,
+ (fname == NULL) ? "" : "()",
+ len,
+ (len == 1) ? "" : "s",
+ nargs + nkeywords);
+ return 0;
+ }
- freelist.entries = PyMem_New(freelistentry_t, len);
+ /* convert tuple args and keyword args in same loop, using kwlist to drive process */
+ for (i = 0; i < len; i++) {
+ keyword = kwlist[i];
+ if (*format == '|') {
+ min = i;
+ format++;
+ }
+ if (IS_END_OF_FORMAT(*format)) {
+ PyErr_Format(PyExc_RuntimeError,
+ "More keyword list entries (%d) than "
+ "format specifiers (%d)", len, i);
+ return cleanreturn(0, freelist);
+ }
+ current_arg = NULL;
+ if (nkeywords) {
+ current_arg = PyDict_GetItemString(keywords, keyword);
+ }
+ if (current_arg) {
+ --nkeywords;
+ if (i < nargs) {
+ /* arg present in tuple and in dict */
+ PyErr_Format(PyExc_TypeError,
+ "Argument given by name ('%s') "
+ "and position (%d)",
+ keyword, i+1);
+ return cleanreturn(0, freelist);
+ }
+ }
+ else if (nkeywords && PyErr_Occurred())
+ return cleanreturn(0, freelist);
+ else if (i < nargs)
+ current_arg = PyTuple_GET_ITEM(args, i);
- nargs = PyTuple_GET_SIZE(args);
- nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords);
- if (nargs + nkeywords > len) {
- PyErr_Format(PyExc_TypeError, "%s%s takes at most %d "
- "argument%s (%d given)",
- (fname == NULL) ? "function" : fname,
- (fname == NULL) ? "" : "()",
- len,
- (len == 1) ? "" : "s",
- nargs + nkeywords);
- return cleanreturn(0, &freelist);
- }
+ if (current_arg) {
+ msg = convertitem(current_arg, &format, p_va, flags,
+ levels, msgbuf, sizeof(msgbuf), &freelist);
+ if (msg) {
+ seterror(i+1, msg, levels, fname, custom_msg);
+ return cleanreturn(0, freelist);
+ }
+ continue;
+ }
- /* convert tuple args and keyword args in same loop, using kwlist to drive process */
- for (i = 0; i < len; i++) {
- keyword = kwlist[i];
- if (*format == '|') {
- min = i;
- format++;
- }
- if (IS_END_OF_FORMAT(*format)) {
- PyErr_Format(PyExc_RuntimeError,
- "More keyword list entries (%d) than "
- "format specifiers (%d)", len, i);
- return cleanreturn(0, &freelist);
- }
- current_arg = NULL;
- if (nkeywords) {
- current_arg = PyDict_GetItemString(keywords, keyword);
- }
- if (current_arg) {
- --nkeywords;
- if (i < nargs) {
- /* arg present in tuple and in dict */
- PyErr_Format(PyExc_TypeError,
- "Argument given by name ('%s') "
- "and position (%d)",
- keyword, i+1);
- return cleanreturn(0, &freelist);
- }
- }
- else if (nkeywords && PyErr_Occurred())
- return cleanreturn(0, &freelist);
- else if (i < nargs)
- current_arg = PyTuple_GET_ITEM(args, i);
-
- if (current_arg) {
- msg = convertitem(current_arg, &format, p_va, flags,
- levels, msgbuf, sizeof(msgbuf), &freelist);
- if (msg) {
- seterror(i+1, msg, levels, fname, custom_msg);
- return cleanreturn(0, &freelist);
- }
- continue;
- }
+ if (i < min) {
+ PyErr_Format(PyExc_TypeError, "Required argument "
+ "'%s' (pos %d) not found",
+ keyword, i+1);
+ return cleanreturn(0, freelist);
+ }
+ /* current code reports success when all required args
+ * fulfilled and no keyword args left, with no further
+ * validation. XXX Maybe skip this in debug build ?
+ */
+ if (!nkeywords)
+ return cleanreturn(1, freelist);
- if (i < min) {
- PyErr_Format(PyExc_TypeError, "Required argument "
- "'%s' (pos %d) not found",
- keyword, i+1);
- return cleanreturn(0, &freelist);
- }
- /* current code reports success when all required args
- * fulfilled and no keyword args left, with no further
- * validation. XXX Maybe skip this in debug build ?
- */
- if (!nkeywords)
- return cleanreturn(1, &freelist);
+ /* We are into optional args, skip thru to any remaining
+ * keyword args */
+ msg = skipitem(&format, p_va, flags);
+ if (msg) {
+ PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg,
+ format);
+ return cleanreturn(0, freelist);
+ }
+ }
- /* We are into optional args, skip thru to any remaining
- * keyword args */
- msg = skipitem(&format, p_va, flags);
- if (msg) {
- PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg,
- format);
- return cleanreturn(0, &freelist);
- }
- }
+ if (!IS_END_OF_FORMAT(*format) && *format != '|') {
+ PyErr_Format(PyExc_RuntimeError,
+ "more argument specifiers than keyword list entries "
+ "(remaining format:'%s')", format);
+ return cleanreturn(0, freelist);
+ }
- if (!IS_END_OF_FORMAT(*format) && *format != '|') {
- PyErr_Format(PyExc_RuntimeError,
- "more argument specifiers than keyword list entries "
- "(remaining format:'%s')", format);
- return cleanreturn(0, &freelist);
- }
+ /* make sure there are no extraneous keyword arguments */
+ if (nkeywords > 0) {
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+ while (PyDict_Next(keywords, &pos, &key, &value)) {
+ int match = 0;
+ char *ks;
+ if (!PyString_Check(key)) {
+ PyErr_SetString(PyExc_TypeError,
+ "keywords must be strings");
+ return cleanreturn(0, freelist);
+ }
+ ks = PyString_AsString(key);
+ for (i = 0; i < len; i++) {
+ if (!strcmp(ks, kwlist[i])) {
+ match = 1;
+ break;
+ }
+ }
+ if (!match) {
+ PyErr_Format(PyExc_TypeError,
+ "'%s' is an invalid keyword "
+ "argument for this function",
+ ks);
+ return cleanreturn(0, freelist);
+ }
+ }
+ }
- /* make sure there are no extraneous keyword arguments */
- if (nkeywords > 0) {
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(keywords, &pos, &key, &value)) {
- int match = 0;
- char *ks;
- if (!PyString_Check(key)) {
- PyErr_SetString(PyExc_TypeError,
- "keywords must be strings");
- return cleanreturn(0, &freelist);
- }
- ks = PyString_AsString(key);
- for (i = 0; i < len; i++) {
- if (!strcmp(ks, kwlist[i])) {
- match = 1;
- break;
- }
- }
- if (!match) {
- PyErr_Format(PyExc_TypeError,
- "'%s' is an invalid keyword "
- "argument for this function",
- ks);
- return cleanreturn(0, &freelist);
- }
- }
- }
-
- return cleanreturn(1, &freelist);
+ return cleanreturn(1, freelist);
}
static char *
skipitem(const char **p_format, va_list *p_va, int flags)
{
- const char *format = *p_format;
- char c = *format++;
-
- switch (c) {
+ const char *format = *p_format;
+ char c = *format++;
- /* simple codes
- * The individual types (second arg of va_arg) are irrelevant */
+ switch (c) {
- case 'b': /* byte -- very short int */
- case 'B': /* byte as bitfield */
- case 'h': /* short int */
- case 'H': /* short int as bitfield */
- case 'i': /* int */
- case 'I': /* int sized bitfield */
- case 'l': /* long int */
- case 'k': /* long int sized bitfield */
+ /* simple codes
+ * The individual types (second arg of va_arg) are irrelevant */
+
+ case 'b': /* byte -- very short int */
+ case 'B': /* byte as bitfield */
+ case 'h': /* short int */
+ case 'H': /* short int as bitfield */
+ case 'i': /* int */
+ case 'I': /* int sized bitfield */
+ case 'l': /* long int */
+ case 'k': /* long int sized bitfield */
#ifdef HAVE_LONG_LONG
- case 'L': /* PY_LONG_LONG */
- case 'K': /* PY_LONG_LONG sized bitfield */
+ case 'L': /* PY_LONG_LONG */
+ case 'K': /* PY_LONG_LONG sized bitfield */
#endif
- case 'f': /* float */
- case 'd': /* double */
+ case 'f': /* float */
+ case 'd': /* double */
#ifndef WITHOUT_COMPLEX
- case 'D': /* complex double */
+ case 'D': /* complex double */
#endif
- case 'c': /* char */
- {
- (void) va_arg(*p_va, void *);
- break;
- }
+ case 'c': /* char */
+ {
+ (void) va_arg(*p_va, void *);
+ break;
+ }
- case 'n': /* Py_ssize_t */
- {
- (void) va_arg(*p_va, Py_ssize_t *);
- break;
- }
-
- /* string codes */
-
- case 'e': /* string with encoding */
- {
- (void) va_arg(*p_va, const char *);
- if (!(*format == 's' || *format == 't'))
- /* after 'e', only 's' and 't' is allowed */
- goto err;
- format++;
- /* explicit fallthrough to string cases */
- }
-
- case 's': /* string */
- case 'z': /* string or None */
+ case 'n': /* Py_ssize_t */
+ {
+ (void) va_arg(*p_va, Py_ssize_t *);
+ break;
+ }
+
+ /* string codes */
+
+ case 'e': /* string with encoding */
+ {
+ (void) va_arg(*p_va, const char *);
+ if (!(*format == 's' || *format == 't'))
+ /* after 'e', only 's' and 't' is allowed */
+ goto err;
+ format++;
+ /* explicit fallthrough to string cases */
+ }
+
+ case 's': /* string */
+ case 'z': /* string or None */
#ifdef Py_USING_UNICODE
- case 'u': /* unicode string */
+ case 'u': /* unicode string */
#endif
- case 't': /* buffer, read-only */
- case 'w': /* buffer, read-write */
- {
- (void) va_arg(*p_va, char **);
- if (*format == '#') {
- if (flags & FLAG_SIZE_T)
- (void) va_arg(*p_va, Py_ssize_t *);
- else
- (void) va_arg(*p_va, int *);
- format++;
- } else if ((c == 's' || c == 'z') && *format == '*') {
- format++;
- }
- break;
- }
+ case 't': /* buffer, read-only */
+ case 'w': /* buffer, read-write */
+ {
+ (void) va_arg(*p_va, char **);
+ if (*format == '#') {
+ if (flags & FLAG_SIZE_T)
+ (void) va_arg(*p_va, Py_ssize_t *);
+ else
+ (void) va_arg(*p_va, int *);
+ format++;
+ } else if ((c == 's' || c == 'z') && *format == '*') {
+ format++;
+ }
+ break;
+ }
- /* object codes */
+ /* object codes */
- case 'S': /* string object */
+ case 'S': /* string object */
#ifdef Py_USING_UNICODE
- case 'U': /* unicode string object */
+ case 'U': /* unicode string object */
#endif
- {
- (void) va_arg(*p_va, PyObject **);
- break;
- }
-
- case 'O': /* object */
- {
- if (*format == '!') {
- format++;
- (void) va_arg(*p_va, PyTypeObject*);
- (void) va_arg(*p_va, PyObject **);
- }
-#if 0
-/* I don't know what this is for */
- else if (*format == '?') {
- inquiry pred = va_arg(*p_va, inquiry);
- format++;
- if ((*pred)(arg)) {
- (void) va_arg(*p_va, PyObject **);
- }
- }
-#endif
- else if (*format == '&') {
- typedef int (*converter)(PyObject *, void *);
- (void) va_arg(*p_va, converter);
- (void) va_arg(*p_va, void *);
- format++;
- }
- else {
- (void) va_arg(*p_va, PyObject **);
- }
- break;
- }
+ {
+ (void) va_arg(*p_va, PyObject **);
+ break;
+ }
- case '(': /* bypass tuple, not handled at all previously */
- {
- char *msg;
- for (;;) {
- if (*format==')')
- break;
- if (IS_END_OF_FORMAT(*format))
- return "Unmatched left paren in format "
- "string";
- msg = skipitem(&format, p_va, flags);
- if (msg)
- return msg;
- }
- format++;
- break;
- }
+ case 'O': /* object */
+ {
+ if (*format == '!') {
+ format++;
+ (void) va_arg(*p_va, PyTypeObject*);
+ (void) va_arg(*p_va, PyObject **);
+ }
+ else if (*format == '&') {
+ typedef int (*converter)(PyObject *, void *);
+ (void) va_arg(*p_va, converter);
+ (void) va_arg(*p_va, void *);
+ format++;
+ }
+ else {
+ (void) va_arg(*p_va, PyObject **);
+ }
+ break;
+ }
- case ')':
- return "Unmatched right paren in format string";
+ case '(': /* bypass tuple, not handled at all previously */
+ {
+ char *msg;
+ for (;;) {
+ if (*format==')')
+ break;
+ if (IS_END_OF_FORMAT(*format))
+ return "Unmatched left paren in format "
+ "string";
+ msg = skipitem(&format, p_va, flags);
+ if (msg)
+ return msg;
+ }
+ format++;
+ break;
+ }
- default:
+ case ')':
+ return "Unmatched right paren in format string";
+
+ default:
err:
- return "impossible<bad format char>";
-
- }
+ return "impossible<bad format char>";
- *p_format = format;
- return NULL;
+ }
+
+ *p_format = format;
+ return NULL;
}
int
PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
{
- Py_ssize_t i, l;
- PyObject **o;
- va_list vargs;
+ Py_ssize_t i, l;
+ PyObject **o;
+ va_list vargs;
#ifdef HAVE_STDARG_PROTOTYPES
- va_start(vargs, max);
+ va_start(vargs, max);
#else
- va_start(vargs);
+ va_start(vargs);
#endif
- assert(min >= 0);
- assert(min <= max);
- if (!PyTuple_Check(args)) {
- PyErr_SetString(PyExc_SystemError,
- "PyArg_UnpackTuple() argument list is not a tuple");
- return 0;
- }
- l = PyTuple_GET_SIZE(args);
- if (l < min) {
- if (name != NULL)
- PyErr_Format(
- PyExc_TypeError,
- "%s expected %s%zd arguments, got %zd",
- name, (min == max ? "" : "at least "), min, l);
- else
- PyErr_Format(
- PyExc_TypeError,
- "unpacked tuple should have %s%zd elements,"
- " but has %zd",
- (min == max ? "" : "at least "), min, l);
- va_end(vargs);
- return 0;
- }
- if (l > max) {
- if (name != NULL)
- PyErr_Format(
- PyExc_TypeError,
- "%s expected %s%zd arguments, got %zd",
- name, (min == max ? "" : "at most "), max, l);
- else
- PyErr_Format(
- PyExc_TypeError,
- "unpacked tuple should have %s%zd elements,"
- " but has %zd",
- (min == max ? "" : "at most "), max, l);
- va_end(vargs);
- return 0;
- }
- for (i = 0; i < l; i++) {
- o = va_arg(vargs, PyObject **);
- *o = PyTuple_GET_ITEM(args, i);
- }
- va_end(vargs);
- return 1;
+ assert(min >= 0);
+ assert(min <= max);
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_SystemError,
+ "PyArg_UnpackTuple() argument list is not a tuple");
+ return 0;
+ }
+ l = PyTuple_GET_SIZE(args);
+ if (l < min) {
+ if (name != NULL)
+ PyErr_Format(
+ PyExc_TypeError,
+ "%s expected %s%zd arguments, got %zd",
+ name, (min == max ? "" : "at least "), min, l);
+ else
+ PyErr_Format(
+ PyExc_TypeError,
+ "unpacked tuple should have %s%zd elements,"
+ " but has %zd",
+ (min == max ? "" : "at least "), min, l);
+ va_end(vargs);
+ return 0;
+ }
+ if (l > max) {
+ if (name != NULL)
+ PyErr_Format(
+ PyExc_TypeError,
+ "%s expected %s%zd arguments, got %zd",
+ name, (min == max ? "" : "at most "), max, l);
+ else
+ PyErr_Format(
+ PyExc_TypeError,
+ "unpacked tuple should have %s%zd elements,"
+ " but has %zd",
+ (min == max ? "" : "at most "), max, l);
+ va_end(vargs);
+ return 0;
+ }
+ for (i = 0; i < l; i++) {
+ o = va_arg(vargs, PyObject **);
+ *o = PyTuple_GET_ITEM(args, i);
+ }
+ va_end(vargs);
+ return 1;
}
/* For type constructors that don't take keyword args
*
- * Sets a TypeError and returns 0 if the kwds dict is
+ * Sets a TypeError and returns 0 if the kwds dict is
* not empty, returns 1 otherwise
*/
int
_PyArg_NoKeywords(const char *funcname, PyObject *kw)
{
- if (kw == NULL)
- return 1;
- if (!PyDict_CheckExact(kw)) {
- PyErr_BadInternalCall();
- return 0;
- }
- if (PyDict_Size(kw) == 0)
- return 1;
-
- PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",
- funcname);
- return 0;
+ if (kw == NULL)
+ return 1;
+ if (!PyDict_CheckExact(kw)) {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+ if (PyDict_Size(kw) == 0)
+ return 1;
+
+ PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",
+ funcname);
+ return 0;
}
#ifdef __cplusplus
};
diff --git a/pypy/module/cpyext/src/modsupport.c b/pypy/module/cpyext/src/modsupport.c
--- a/pypy/module/cpyext/src/modsupport.c
+++ b/pypy/module/cpyext/src/modsupport.c
@@ -33,41 +33,41 @@
static int
countformat(const char *format, int endchar)
{
- int count = 0;
- int level = 0;
- while (level > 0 || *format != endchar) {
- switch (*format) {
- case '\0':
- /* Premature end */
- PyErr_SetString(PyExc_SystemError,
- "unmatched paren in format");
- return -1;
- case '(':
- case '[':
- case '{':
- if (level == 0)
- count++;
- level++;
- break;
- case ')':
- case ']':
- case '}':
- level--;
- break;
- case '#':
- case '&':
- case ',':
- case ':':
- case ' ':
- case '\t':
- break;
- default:
- if (level == 0)
- count++;
- }
- format++;
- }
- return count;
+ int count = 0;
+ int level = 0;
+ while (level > 0 || *format != endchar) {
+ switch (*format) {
+ case '\0':
+ /* Premature end */
+ PyErr_SetString(PyExc_SystemError,
+ "unmatched paren in format");
+ return -1;
+ case '(':
+ case '[':
+ case '{':
+ if (level == 0)
+ count++;
+ level++;
+ break;
+ case ')':
+ case ']':
+ case '}':
+ level--;
+ break;
+ case '#':
+ case '&':
+ case ',':
+ case ':':
+ case ' ':
+ case '\t':
+ break;
+ default:
+ if (level == 0)
+ count++;
+ }
+ format++;
+ }
+ return count;
}
@@ -83,582 +83,435 @@
static PyObject *
do_mkdict(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{
- PyObject *d;
- int i;
- int itemfailed = 0;
- if (n < 0)
- return NULL;
- if ((d = PyDict_New()) == NULL)
- return NULL;
- /* Note that we can't bail immediately on error as this will leak
- refcounts on any 'N' arguments. */
- for (i = 0; i < n; i+= 2) {
- PyObject *k, *v;
- int err;
- k = do_mkvalue(p_format, p_va, flags);
- if (k == NULL) {
- itemfailed = 1;
- Py_INCREF(Py_None);
- k = Py_None;
- }
- v = do_mkvalue(p_format, p_va, flags);
- if (v == NULL) {
- itemfailed = 1;
- Py_INCREF(Py_None);
- v = Py_None;
- }
- err = PyDict_SetItem(d, k, v);
- Py_DECREF(k);
- Py_DECREF(v);
- if (err < 0 || itemfailed) {
- Py_DECREF(d);
- return NULL;
- }
- }
- if (d != NULL && **p_format != endchar) {
- Py_DECREF(d);
- d = NULL;
- PyErr_SetString(PyExc_SystemError,
- "Unmatched paren in format");
- }
- else if (endchar)
- ++*p_format;
- return d;
+ PyObject *d;
+ int i;
+ int itemfailed = 0;
+ if (n < 0)
+ return NULL;
+ if ((d = PyDict_New()) == NULL)
+ return NULL;
+ /* Note that we can't bail immediately on error as this will leak
+ refcounts on any 'N' arguments. */
+ for (i = 0; i < n; i+= 2) {
+ PyObject *k, *v;
+ int err;
+ k = do_mkvalue(p_format, p_va, flags);
+ if (k == NULL) {
+ itemfailed = 1;
+ Py_INCREF(Py_None);
+ k = Py_None;
+ }
+ v = do_mkvalue(p_format, p_va, flags);
+ if (v == NULL) {
+ itemfailed = 1;
+ Py_INCREF(Py_None);
+ v = Py_None;
+ }
+ err = PyDict_SetItem(d, k, v);
+ Py_DECREF(k);
+ Py_DECREF(v);
+ if (err < 0 || itemfailed) {
+ Py_DECREF(d);
+ return NULL;
+ }
+ }
+ if (d != NULL && **p_format != endchar) {
+ Py_DECREF(d);
+ d = NULL;
+ PyErr_SetString(PyExc_SystemError,
+ "Unmatched paren in format");
+ }
+ else if (endchar)
+ ++*p_format;
+ return d;
}
static PyObject *
do_mklist(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{
- PyObject *v;
- int i;
- int itemfailed = 0;
- if (n < 0)
- return NULL;
- v = PyList_New(n);
- if (v == NULL)
- return NULL;
- /* Note that we can't bail immediately on error as this will leak
- refcounts on any 'N' arguments. */
- for (i = 0; i < n; i++) {
- PyObject *w = do_mkvalue(p_format, p_va, flags);
- if (w == NULL) {
- itemfailed = 1;
- Py_INCREF(Py_None);
- w = Py_None;
- }
- PyList_SET_ITEM(v, i, w);
- }
+ PyObject *v;
+ int i;
+ int itemfailed = 0;
+ if (n < 0)
+ return NULL;
+ v = PyList_New(n);
+ if (v == NULL)
+ return NULL;
+ /* Note that we can't bail immediately on error as this will leak
+ refcounts on any 'N' arguments. */
+ for (i = 0; i < n; i++) {
+ PyObject *w = do_mkvalue(p_format, p_va, flags);
+ if (w == NULL) {
+ itemfailed = 1;
+ Py_INCREF(Py_None);
+ w = Py_None;
+ }
+ PyList_SET_ITEM(v, i, w);
+ }
- if (itemfailed) {
- /* do_mkvalue() should have already set an error */
- Py_DECREF(v);
- return NULL;
- }
- if (**p_format != endchar) {
- Py_DECREF(v);
- PyErr_SetString(PyExc_SystemError,
- "Unmatched paren in format");
- return NULL;
- }
- if (endchar)
- ++*p_format;
- return v;
+ if (itemfailed) {
+ /* do_mkvalue() should have already set an error */
+ Py_DECREF(v);
+ return NULL;
+ }
+ if (**p_format != endchar) {
+ Py_DECREF(v);
+ PyErr_SetString(PyExc_SystemError,
+ "Unmatched paren in format");
+ return NULL;
+ }
+ if (endchar)
+ ++*p_format;
+ return v;
}
#ifdef Py_USING_UNICODE
static int
_ustrlen(Py_UNICODE *u)
{
- int i = 0;
- Py_UNICODE *v = u;
- while (*v != 0) { i++; v++; }
- return i;
+ int i = 0;
+ Py_UNICODE *v = u;
+ while (*v != 0) { i++; v++; }
+ return i;
}
#endif
static PyObject *
do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{
- PyObject *v;
- int i;
- int itemfailed = 0;
- if (n < 0)
- return NULL;
- if ((v = PyTuple_New(n)) == NULL)
- return NULL;
- /* Note that we can't bail immediately on error as this will leak
- refcounts on any 'N' arguments. */
- for (i = 0; i < n; i++) {
- PyObject *w = do_mkvalue(p_format, p_va, flags);
- if (w == NULL) {
- itemfailed = 1;
- Py_INCREF(Py_None);
- w = Py_None;
- }
- PyTuple_SET_ITEM(v, i, w);
- }
- if (itemfailed) {
- /* do_mkvalue() should have already set an error */
- Py_DECREF(v);
- return NULL;
- }
- if (**p_format != endchar) {
- Py_DECREF(v);
- PyErr_SetString(PyExc_SystemError,
- "Unmatched paren in format");
- return NULL;
- }
- if (endchar)
- ++*p_format;
- return v;
+ PyObject *v;
+ int i;
+ int itemfailed = 0;
+ if (n < 0)
+ return NULL;
+ if ((v = PyTuple_New(n)) == NULL)
+ return NULL;
+ /* Note that we can't bail immediately on error as this will leak
+ refcounts on any 'N' arguments. */
+ for (i = 0; i < n; i++) {
+ PyObject *w = do_mkvalue(p_format, p_va, flags);
+ if (w == NULL) {
+ itemfailed = 1;
+ Py_INCREF(Py_None);
+ w = Py_None;
+ }
+ PyTuple_SET_ITEM(v, i, w);
+ }
+ if (itemfailed) {
+ /* do_mkvalue() should have already set an error */
+ Py_DECREF(v);
+ return NULL;
+ }
+ if (**p_format != endchar) {
+ Py_DECREF(v);
+ PyErr_SetString(PyExc_SystemError,
+ "Unmatched paren in format");
+ return NULL;
+ }
+ if (endchar)
+ ++*p_format;
+ return v;
}
static PyObject *
do_mkvalue(const char **p_format, va_list *p_va, int flags)
{
- for (;;) {
- switch (*(*p_format)++) {
- case '(':
- return do_mktuple(p_format, p_va, ')',
- countformat(*p_format, ')'), flags);
+ for (;;) {
+ switch (*(*p_format)++) {
+ case '(':
+ return do_mktuple(p_format, p_va, ')',
+ countformat(*p_format, ')'), flags);
- case '[':
- return do_mklist(p_format, p_va, ']',
- countformat(*p_format, ']'), flags);
+ case '[':
+ return do_mklist(p_format, p_va, ']',
+ countformat(*p_format, ']'), flags);
- case '{':
- return do_mkdict(p_format, p_va, '}',
- countformat(*p_format, '}'), flags);
+ case '{':
+ return do_mkdict(p_format, p_va, '}',
+ countformat(*p_format, '}'), flags);
- case 'b':
- case 'B':
- case 'h':
- case 'i':
- return PyInt_FromLong((long)va_arg(*p_va, int));
-
- case 'H':
- return PyInt_FromLong((long)va_arg(*p_va, unsigned int));
+ case 'b':
+ case 'B':
+ case 'h':
+ case 'i':
+ return PyInt_FromLong((long)va_arg(*p_va, int));
- case 'I':
- {
- unsigned int n;
- n = va_arg(*p_va, unsigned int);
- if (n > (unsigned long)PyInt_GetMax())
- return PyLong_FromUnsignedLong((unsigned long)n);
- else
- return PyInt_FromLong(n);
- }
-
- case 'n':
+ case 'H':
+ return PyInt_FromLong((long)va_arg(*p_va, unsigned int));
+
+ case 'I':
+ {
+ unsigned int n;
+ n = va_arg(*p_va, unsigned int);
+ if (n > (unsigned long)PyInt_GetMax())
+ return PyLong_FromUnsignedLong((unsigned long)n);
+ else
+ return PyInt_FromLong(n);
+ }
+
+ case 'n':
#if SIZEOF_SIZE_T!=SIZEOF_LONG
- return PyInt_FromSsize_t(va_arg(*p_va, Py_ssize_t));
+ return PyInt_FromSsize_t(va_arg(*p_va, Py_ssize_t));
#endif
- /* Fall through from 'n' to 'l' if Py_ssize_t is long */
- case 'l':
- return PyInt_FromLong(va_arg(*p_va, long));
+ /* Fall through from 'n' to 'l' if Py_ssize_t is long */
+ case 'l':
+ return PyInt_FromLong(va_arg(*p_va, long));
- case 'k':
- {
- unsigned long n;
- n = va_arg(*p_va, unsigned long);
- if (n > (unsigned long)PyInt_GetMax())
- return PyLong_FromUnsignedLong(n);
- else
- return PyInt_FromLong(n);
- }
+ case 'k':
+ {
+ unsigned long n;
+ n = va_arg(*p_va, unsigned long);
+ if (n > (unsigned long)PyInt_GetMax())
+ return PyLong_FromUnsignedLong(n);
+ else
+ return PyInt_FromLong(n);
+ }
#ifdef HAVE_LONG_LONG
- case 'L':
- return PyLong_FromLongLong((PY_LONG_LONG)va_arg(*p_va, PY_LONG_LONG));
+ case 'L':
+ return PyLong_FromLongLong((PY_LONG_LONG)va_arg(*p_va, PY_LONG_LONG));
- case 'K':
- return PyLong_FromUnsignedLongLong((PY_LONG_LONG)va_arg(*p_va, unsigned PY_LONG_LONG));
+ case 'K':
+ return PyLong_FromUnsignedLongLong((PY_LONG_LONG)va_arg(*p_va, unsigned PY_LONG_LONG));
#endif
#ifdef Py_USING_UNICODE
- case 'u':
- {
- PyObject *v;
- Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *);
- Py_ssize_t n;
- if (**p_format == '#') {
- ++*p_format;
- if (flags & FLAG_SIZE_T)
- n = va_arg(*p_va, Py_ssize_t);
- else
- n = va_arg(*p_va, int);
- }
- else
- n = -1;
- if (u == NULL) {
- v = Py_None;
- Py_INCREF(v);
- }
- else {
- if (n < 0)
- n = _ustrlen(u);
- v = PyUnicode_FromUnicode(u, n);
- }
- return v;
- }
+ case 'u':
+ {
+ PyObject *v;
+ Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *);
+ Py_ssize_t n;
+ if (**p_format == '#') {
+ ++*p_format;
+ if (flags & FLAG_SIZE_T)
+ n = va_arg(*p_va, Py_ssize_t);
+ else
+ n = va_arg(*p_va, int);
+ }
+ else
+ n = -1;
+ if (u == NULL) {
+ v = Py_None;
+ Py_INCREF(v);
+ }
+ else {
+ if (n < 0)
+ n = _ustrlen(u);
+ v = PyUnicode_FromUnicode(u, n);
+ }
+ return v;
+ }
#endif
- case 'f':
- case 'd':
- return PyFloat_FromDouble(
- (double)va_arg(*p_va, va_double));
+ case 'f':
+ case 'd':
+ return PyFloat_FromDouble(
+ (double)va_arg(*p_va, va_double));
#ifndef WITHOUT_COMPLEX
- case 'D':
- return PyComplex_FromCComplex(
- *((Py_complex *)va_arg(*p_va, Py_complex *)));
+ case 'D':
+ return PyComplex_FromCComplex(
+ *((Py_complex *)va_arg(*p_va, Py_complex *)));
#endif /* WITHOUT_COMPLEX */
- case 'c':
- {
- char p[1];
- p[0] = (char)va_arg(*p_va, int);
- return PyString_FromStringAndSize(p, 1);
- }
+ case 'c':
+ {
+ char p[1];
+ p[0] = (char)va_arg(*p_va, int);
+ return PyString_FromStringAndSize(p, 1);
+ }
- case 's':
- case 'z':
- {
- PyObject *v;
- char *str = va_arg(*p_va, char *);
- Py_ssize_t n;
- if (**p_format == '#') {
- ++*p_format;
- if (flags & FLAG_SIZE_T)
- n = va_arg(*p_va, Py_ssize_t);
- else
- n = va_arg(*p_va, int);
- }
- else
- n = -1;
- if (str == NULL) {
- v = Py_None;
- Py_INCREF(v);
- }
- else {
- if (n < 0) {
- size_t m = strlen(str);
- if (m > PY_SSIZE_T_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "string too long for Python string");
- return NULL;
- }
- n = (Py_ssize_t)m;
- }
- v = PyString_FromStringAndSize(str, n);
- }
- return v;
- }
+ case 's':
+ case 'z':
+ {
+ PyObject *v;
+ char *str = va_arg(*p_va, char *);
+ Py_ssize_t n;
+ if (**p_format == '#') {
+ ++*p_format;
+ if (flags & FLAG_SIZE_T)
+ n = va_arg(*p_va, Py_ssize_t);
+ else
+ n = va_arg(*p_va, int);
+ }
+ else
+ n = -1;
+ if (str == NULL) {
+ v = Py_None;
+ Py_INCREF(v);
+ }
+ else {
+ if (n < 0) {
+ size_t m = strlen(str);
+ if (m > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "string too long for Python string");
+ return NULL;
+ }
+ n = (Py_ssize_t)m;
+ }
+ v = PyString_FromStringAndSize(str, n);
+ }
+ return v;
+ }
- case 'N':
- case 'S':
- case 'O':
- if (**p_format == '&') {
- typedef PyObject *(*converter)(void *);
- converter func = va_arg(*p_va, converter);
- void *arg = va_arg(*p_va, void *);
- ++*p_format;
- return (*func)(arg);
- }
- else {
- PyObject *v;
- v = va_arg(*p_va, PyObject *);
- if (v != NULL) {
- if (*(*p_format - 1) != 'N')
- Py_INCREF(v);
- }
- else if (!PyErr_Occurred())
- /* If a NULL was passed
- * because a call that should
- * have constructed a value
- * failed, that's OK, and we
- * pass the error on; but if
- * no error occurred it's not
- * clear that the caller knew
- * what she was doing. */
- PyErr_SetString(PyExc_SystemError,
- "NULL object passed to Py_BuildValue");
- return v;
- }
+ case 'N':
+ case 'S':
+ case 'O':
+ if (**p_format == '&') {
+ typedef PyObject *(*converter)(void *);
+ converter func = va_arg(*p_va, converter);
+ void *arg = va_arg(*p_va, void *);
+ ++*p_format;
+ return (*func)(arg);
+ }
+ else {
+ PyObject *v;
+ v = va_arg(*p_va, PyObject *);
+ if (v != NULL) {
+ if (*(*p_format - 1) != 'N')
+ Py_INCREF(v);
+ }
+ else if (!PyErr_Occurred())
+ /* If a NULL was passed
+ * because a call that should
+ * have constructed a value
+ * failed, that's OK, and we
+ * pass the error on; but if
+ * no error occurred it's not
+ * clear that the caller knew
+ * what she was doing. */
+ PyErr_SetString(PyExc_SystemError,
+ "NULL object passed to Py_BuildValue");
+ return v;
+ }
- case ':':
- case ',':
- case ' ':
- case '\t':
- break;
+ case ':':
+ case ',':
+ case ' ':
+ case '\t':
+ break;
- default:
- PyErr_SetString(PyExc_SystemError,
- "bad format char passed to Py_BuildValue");
- return NULL;
+ default:
+ PyErr_SetString(PyExc_SystemError,
+ "bad format char passed to Py_BuildValue");
+ return NULL;
- }
- }
+ }
+ }
}
PyObject *
Py_BuildValue(const char *format, ...)
{
- va_list va;
- PyObject* retval;
- va_start(va, format);
- retval = va_build_value(format, va, 0);
- va_end(va);
- return retval;
+ va_list va;
+ PyObject* retval;
+ va_start(va, format);
+ retval = va_build_value(format, va, 0);
+ va_end(va);
+ return retval;
}
PyObject *
_Py_BuildValue_SizeT(const char *format, ...)
{
- va_list va;
- PyObject* retval;
- va_start(va, format);
- retval = va_build_value(format, va, FLAG_SIZE_T);
- va_end(va);
- return retval;
+ va_list va;
+ PyObject* retval;
+ va_start(va, format);
+ retval = va_build_value(format, va, FLAG_SIZE_T);
+ va_end(va);
+ return retval;
}
PyObject *
Py_VaBuildValue(const char *format, va_list va)
{
- return va_build_value(format, va, 0);
+ return va_build_value(format, va, 0);
}
PyObject *
_Py_VaBuildValue_SizeT(const char *format, va_list va)
{
- return va_build_value(format, va, FLAG_SIZE_T);
+ return va_build_value(format, va, FLAG_SIZE_T);
}
static PyObject *
va_build_value(const char *format, va_list va, int flags)
{
- const char *f = format;
- int n = countformat(f, '\0');
- va_list lva;
+ const char *f = format;
+ int n = countformat(f, '\0');
+ va_list lva;
#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
+ memcpy(lva, va, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(lva, va);
+ __va_copy(lva, va);
#else
- lva = va;
+ lva = va;
#endif
#endif
- if (n < 0)
- return NULL;
- if (n == 0) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- if (n == 1)
- return do_mkvalue(&f, &lva, flags);
- return do_mktuple(&f, &lva, '\0', n, flags);
+ if (n < 0)
+ return NULL;
+ if (n == 0) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ if (n == 1)
+ return do_mkvalue(&f, &lva, flags);
+ return do_mktuple(&f, &lva, '\0', n, flags);
}
PyObject *
PyEval_CallFunction(PyObject *obj, const char *format, ...)
{
- va_list vargs;
- PyObject *args;
- PyObject *res;
+ va_list vargs;
+ PyObject *args;
+ PyObject *res;
- va_start(vargs, format);
+ va_start(vargs, format);
- args = Py_VaBuildValue(format, vargs);
- va_end(vargs);
+ args = Py_VaBuildValue(format, vargs);
+ va_end(vargs);
- if (args == NULL)
- return NULL;
+ if (args == NULL)
+ return NULL;
- res = PyEval_CallObject(obj, args);
- Py_DECREF(args);
+ res = PyEval_CallObject(obj, args);
+ Py_DECREF(args);
- return res;
+ return res;
}
PyObject *
PyEval_CallMethod(PyObject *obj, const char *methodname, const char *format, ...)
{
- va_list vargs;
- PyObject *meth;
- PyObject *args;
- PyObject *res;
+ va_list vargs;
+ PyObject *meth;
+ PyObject *args;
+ PyObject *res;
- meth = PyObject_GetAttrString(obj, methodname);
- if (meth == NULL)
- return NULL;
+ meth = PyObject_GetAttrString(obj, methodname);
+ if (meth == NULL)
+ return NULL;
- va_start(vargs, format);
+ va_start(vargs, format);
- args = Py_VaBuildValue(format, vargs);
- va_end(vargs);
+ args = Py_VaBuildValue(format, vargs);
+ va_end(vargs);
- if (args == NULL) {
- Py_DECREF(meth);
- return NULL;
- }
+ if (args == NULL) {
+ Py_DECREF(meth);
+ return NULL;
+ }
- res = PyEval_CallObject(meth, args);
- Py_DECREF(meth);
- Py_DECREF(args);
+ res = PyEval_CallObject(meth, args);
+ Py_DECREF(meth);
+ Py_DECREF(args);
- return res;
-}
-
-static PyObject*
-call_function_tail(PyObject *callable, PyObject *args)
-{
- PyObject *retval;
-
- if (args == NULL)
- return NULL;
-
- if (!PyTuple_Check(args)) {
- PyObject *a;
-
- a = PyTuple_New(1);
- if (a == NULL) {
- Py_DECREF(args);
- return NULL;
- }
- PyTuple_SET_ITEM(a, 0, args);
- args = a;
- }
- retval = PyObject_Call(callable, args, NULL);
-
- Py_DECREF(args);
-
- return retval;
-}
-
-PyObject *
-PyObject_CallFunction(PyObject *callable, const char *format, ...)
-{
- va_list va;
- PyObject *args;
-
- if (format && *format) {
- va_start(va, format);
- args = Py_VaBuildValue(format, va);
- va_end(va);
- }
- else
- args = PyTuple_New(0);
-
- return call_function_tail(callable, args);
-}
-
-PyObject *
-PyObject_CallMethod(PyObject *o, const char *name, const char *format, ...)
-{
- va_list va;
- PyObject *args;
- PyObject *func = NULL;
- PyObject *retval = NULL;
-
- func = PyObject_GetAttrString(o, name);
- if (func == NULL) {
- PyErr_SetString(PyExc_AttributeError, name);
- return 0;
- }
-
- if (format && *format) {
- va_start(va, format);
- args = Py_VaBuildValue(format, va);
- va_end(va);
- }
- else
- args = PyTuple_New(0);
-
- retval = call_function_tail(func, args);
-
- exit:
- /* args gets consumed in call_function_tail */
- Py_XDECREF(func);
-
- return retval;
-}
-
-static PyObject *
-objargs_mktuple(va_list va)
-{
- int i, n = 0;
- va_list countva;
- PyObject *result, *tmp;
-
-#ifdef VA_LIST_IS_ARRAY
- memcpy(countva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(countva, va);
-#else
- countva = va;
-#endif
-#endif
-
- while (((PyObject *)va_arg(countva, PyObject *)) != NULL)
- ++n;
- result = PyTuple_New(n);
- if (result != NULL && n > 0) {
- for (i = 0; i < n; ++i) {
- tmp = (PyObject *)va_arg(va, PyObject *);
- Py_INCREF(tmp);
- PyTuple_SET_ITEM(result, i, tmp);
- }
- }
- return result;
-}
-
-PyObject *
-PyObject_CallFunctionObjArgs(PyObject *callable, ...)
-{
- PyObject *args, *tmp;
- va_list vargs;
-
- /* count the args */
- va_start(vargs, callable);
- args = objargs_mktuple(vargs);
- va_end(vargs);
- if (args == NULL)
- return NULL;
- tmp = PyObject_Call(callable, args, NULL);
- Py_DECREF(args);
-
- return tmp;
-}
-
-PyObject *
-PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
-{
- PyObject *args, *tmp;
- va_list vargs;
-
- callable = PyObject_GetAttr(callable, name);
- if (callable == NULL)
- return NULL;
-
- /* count the args */
- va_start(vargs, name);
- args = objargs_mktuple(vargs);
- va_end(vargs);
- if (args == NULL) {
- Py_DECREF(callable);
- return NULL;
- }
- tmp = PyObject_Call(callable, args, NULL);
- Py_DECREF(args);
- Py_DECREF(callable);
-
- return tmp;
+ return res;
}
/* returns -1 in case of error, 0 if a new key was added, 1 if the key
@@ -666,67 +519,67 @@
static int
_PyModule_AddObject_NoConsumeRef(PyObject *m, const char *name, PyObject *o)
{
- PyObject *dict, *prev;
- if (!PyModule_Check(m)) {
- PyErr_SetString(PyExc_TypeError,
- "PyModule_AddObject() needs module as first arg");
- return -1;
- }
- if (!o) {
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "PyModule_AddObject() needs non-NULL value");
- return -1;
- }
+ PyObject *dict, *prev;
+ if (!PyModule_Check(m)) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs module as first arg");
+ return -1;
+ }
+ if (!o) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs non-NULL value");
+ return -1;
+ }
- dict = PyModule_GetDict(m);
- if (dict == NULL) {
- /* Internal error -- modules must have a dict! */
- PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
- PyModule_GetName(m));
- return -1;
- }
- prev = PyDict_GetItemString(dict, name);
- if (PyDict_SetItemString(dict, name, o))
- return -1;
- return prev != NULL;
+ dict = PyModule_GetDict(m);
+ if (dict == NULL) {
+ /* Internal error -- modules must have a dict! */
+ PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
+ PyModule_GetName(m));
+ return -1;
+ }
+ prev = PyDict_GetItemString(dict, name);
+ if (PyDict_SetItemString(dict, name, o))
+ return -1;
+ return prev != NULL;
}
int
PyModule_AddObject(PyObject *m, const char *name, PyObject *o)
{
- int result = _PyModule_AddObject_NoConsumeRef(m, name, o);
- /* XXX WORKAROUND for a common misusage of PyModule_AddObject:
- for the common case of adding a new key, we don't consume a
- reference, but instead just leak it away. The issue is that
- people generally don't realize that this function consumes a
- reference, because on CPython the reference is still stored
- on the dictionary. */
- if (result != 0)
- Py_DECREF(o);
- return result < 0 ? -1 : 0;
+ int result = _PyModule_AddObject_NoConsumeRef(m, name, o);
+ /* XXX WORKAROUND for a common misusage of PyModule_AddObject:
+ for the common case of adding a new key, we don't consume a
+ reference, but instead just leak it away. The issue is that
+ people generally don't realize that this function consumes a
+ reference, because on CPython the reference is still stored
+ on the dictionary. */
+ if (result != 0)
+ Py_DECREF(o);
+ return result < 0 ? -1 : 0;
}
-int
+int
PyModule_AddIntConstant(PyObject *m, const char *name, long value)
{
- int result;
- PyObject *o = PyInt_FromLong(value);
- if (!o)
- return -1;
- result = _PyModule_AddObject_NoConsumeRef(m, name, o);
- Py_DECREF(o);
- return result < 0 ? -1 : 0;
+ int result;
+ PyObject *o = PyInt_FromLong(value);
+ if (!o)
+ return -1;
+ result = _PyModule_AddObject_NoConsumeRef(m, name, o);
+ Py_DECREF(o);
+ return result < 0 ? -1 : 0;
}
-int
+int
PyModule_AddStringConstant(PyObject *m, const char *name, const char *value)
{
- int result;
- PyObject *o = PyString_FromString(value);
- if (!o)
- return -1;
- result = _PyModule_AddObject_NoConsumeRef(m, name, o);
- Py_DECREF(o);
- return result < 0 ? -1 : 0;
+ int result;
+ PyObject *o = PyString_FromString(value);
+ if (!o)
+ return -1;
+ result = _PyModule_AddObject_NoConsumeRef(m, name, o);
+ Py_DECREF(o);
+ return result < 0 ? -1 : 0;
}
diff --git a/pypy/module/cpyext/src/mysnprintf.c b/pypy/module/cpyext/src/mysnprintf.c
--- a/pypy/module/cpyext/src/mysnprintf.c
+++ b/pypy/module/cpyext/src/mysnprintf.c
@@ -20,86 +20,86 @@
Return value (rv):
- When 0 <= rv < size, the output conversion was unexceptional, and
- rv characters were written to str (excluding a trailing \0 byte at
- str[rv]).
+ When 0 <= rv < size, the output conversion was unexceptional, and
+ rv characters were written to str (excluding a trailing \0 byte at
+ str[rv]).
- When rv >= size, output conversion was truncated, and a buffer of
- size rv+1 would have been needed to avoid truncation. str[size-1]
- is \0 in this case.
+ When rv >= size, output conversion was truncated, and a buffer of
+ size rv+1 would have been needed to avoid truncation. str[size-1]
+ is \0 in this case.
- When rv < 0, "something bad happened". str[size-1] is \0 in this
- case too, but the rest of str is unreliable. It could be that
- an error in format codes was detected by libc, or on platforms
- with a non-C99 vsnprintf simply that the buffer wasn't big enough
- to avoid truncation, or on platforms without any vsnprintf that
- PyMem_Malloc couldn't obtain space for a temp buffer.
+ When rv < 0, "something bad happened". str[size-1] is \0 in this
+ case too, but the rest of str is unreliable. It could be that
+ an error in format codes was detected by libc, or on platforms
+ with a non-C99 vsnprintf simply that the buffer wasn't big enough
+ to avoid truncation, or on platforms without any vsnprintf that
+ PyMem_Malloc couldn't obtain space for a temp buffer.
CAUTION: Unlike C99, str != NULL and size > 0 are required.
*/
int
+PyOS_snprintf(char *str, size_t size, const char *format, ...)
+{
+ int rc;
+ va_list va;
+
+ va_start(va, format);
+ rc = PyOS_vsnprintf(str, size, format, va);
+ va_end(va);
+ return rc;
+}
+
+int
PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
{
- int len; /* # bytes written, excluding \0 */
+ int len; /* # bytes written, excluding \0 */
#ifdef HAVE_SNPRINTF
#define _PyOS_vsnprintf_EXTRA_SPACE 1
#else
#define _PyOS_vsnprintf_EXTRA_SPACE 512
- char *buffer;
+ char *buffer;
#endif
- assert(str != NULL);
- assert(size > 0);
- assert(format != NULL);
- /* We take a size_t as input but return an int. Sanity check
- * our input so that it won't cause an overflow in the
- * vsnprintf return value or the buffer malloc size. */
- if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) {
- len = -666;
- goto Done;
- }
+ assert(str != NULL);
+ assert(size > 0);
+ assert(format != NULL);
+ /* We take a size_t as input but return an int. Sanity check
+ * our input so that it won't cause an overflow in the
+ * vsnprintf return value or the buffer malloc size. */
+ if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) {
+ len = -666;
+ goto Done;
+ }
#ifdef HAVE_SNPRINTF
- len = vsnprintf(str, size, format, va);
+ len = vsnprintf(str, size, format, va);
#else
- /* Emulate it. */
- buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE);
- if (buffer == NULL) {
- len = -666;
- goto Done;
- }
+ /* Emulate it. */
+ buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE);
+ if (buffer == NULL) {
+ len = -666;
+ goto Done;
+ }
- len = vsprintf(buffer, format, va);
- if (len < 0)
- /* ignore the error */;
+ len = vsprintf(buffer, format, va);
+ if (len < 0)
+ /* ignore the error */;
- else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE)
- Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
+ else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE)
+ Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
- else {
- const size_t to_copy = (size_t)len < size ?
- (size_t)len : size - 1;
- assert(to_copy < size);
- memcpy(str, buffer, to_copy);
- str[to_copy] = '\0';
- }
- PyMem_FREE(buffer);
+ else {
+ const size_t to_copy = (size_t)len < size ?
+ (size_t)len : size - 1;
+ assert(to_copy < size);
+ memcpy(str, buffer, to_copy);
+ str[to_copy] = '\0';
+ }
+ PyMem_FREE(buffer);
#endif
Done:
- if (size > 0)
- str[size-1] = '\0';
- return len;
+ if (size > 0)
+ str[size-1] = '\0';
+ return len;
#undef _PyOS_vsnprintf_EXTRA_SPACE
}
-
-int
-PyOS_snprintf(char *str, size_t size, const char *format, ...)
-{
- int rc;
- va_list va;
-
- va_start(va, format);
- rc = PyOS_vsnprintf(str, size, format, va);
- va_end(va);
- return rc;
-}
diff --git a/pypy/module/cpyext/src/object.c b/pypy/module/cpyext/src/object.c
deleted file mode 100644
--- a/pypy/module/cpyext/src/object.c
+++ /dev/null
@@ -1,91 +0,0 @@
-// contains code from abstract.c
-#include <Python.h>
-
-
-static PyObject *
-null_error(void)
-{
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_SystemError,
- "null argument to internal routine");
- return NULL;
-}
-
-int PyObject_AsReadBuffer(PyObject *obj,
- const void **buffer,
- Py_ssize_t *buffer_len)
-{
- PyBufferProcs *pb;
- void *pp;
- Py_ssize_t len;
-
- if (obj == NULL || buffer == NULL || buffer_len == NULL) {
- null_error();
- return -1;
- }
- pb = obj->ob_type->tp_as_buffer;
- if (pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "expected a readable buffer object");
- return -1;
- }
- if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
- PyErr_SetString(PyExc_TypeError,
- "expected a single-segment buffer object");
- return -1;
- }
- len = (*pb->bf_getreadbuffer)(obj, 0, &pp);
- if (len < 0)
- return -1;
- *buffer = pp;
- *buffer_len = len;
- return 0;
-}
-
-int PyObject_AsWriteBuffer(PyObject *obj,
- void **buffer,
- Py_ssize_t *buffer_len)
-{
- PyBufferProcs *pb;
- void*pp;
- Py_ssize_t len;
-
- if (obj == NULL || buffer == NULL || buffer_len == NULL) {
- null_error();
- return -1;
- }
- pb = obj->ob_type->tp_as_buffer;
- if (pb == NULL ||
- pb->bf_getwritebuffer == NULL ||
- pb->bf_getsegcount == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "expected a writeable buffer object");
- return -1;
- }
- if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
- PyErr_SetString(PyExc_TypeError,
- "expected a single-segment buffer object");
- return -1;
- }
- len = (*pb->bf_getwritebuffer)(obj,0,&pp);
- if (len < 0)
- return -1;
- *buffer = pp;
- *buffer_len = len;
- return 0;
-}
-
-int
-PyObject_CheckReadBuffer(PyObject *obj)
-{
- PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
-
- if (pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL ||
- (*pb->bf_getsegcount)(obj, NULL) != 1)
- return 0;
- return 1;
-}
diff --git a/pypy/module/cpyext/src/pyerrors.c b/pypy/module/cpyext/src/pyerrors.c
--- a/pypy/module/cpyext/src/pyerrors.c
+++ b/pypy/module/cpyext/src/pyerrors.c
@@ -4,72 +4,75 @@
PyObject *
PyErr_Format(PyObject *exception, const char *format, ...)
{
- va_list vargs;
- PyObject* string;
+ va_list vargs;
+ PyObject* string;
#ifdef HAVE_STDARG_PROTOTYPES
- va_start(vargs, format);
+ va_start(vargs, format);
#else
- va_start(vargs);
+ va_start(vargs);
#endif
- string = PyString_FromFormatV(format, vargs);
- PyErr_SetObject(exception, string);
- Py_XDECREF(string);
- va_end(vargs);
- return NULL;
+ string = PyString_FromFormatV(format, vargs);
+ PyErr_SetObject(exception, string);
+ Py_XDECREF(string);
+ va_end(vargs);
+ return NULL;
}
+
+
PyObject *
PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
{
- char *dot;
- PyObject *modulename = NULL;
- PyObject *classname = NULL;
- PyObject *mydict = NULL;
- PyObject *bases = NULL;
- PyObject *result = NULL;
- dot = strrchr(name, '.');
- if (dot == NULL) {
- PyErr_SetString(PyExc_SystemError,
- "PyErr_NewException: name must be module.class");
- return NULL;
- }
- if (base == NULL)
- base = PyExc_Exception;
- if (dict == NULL) {
- dict = mydict = PyDict_New();
- if (dict == NULL)
- goto failure;
- }
- if (PyDict_GetItemString(dict, "__module__") == NULL) {
- modulename = PyString_FromStringAndSize(name,
- (Py_ssize_t)(dot-name));
- if (modulename == NULL)
- goto failure;
- if (PyDict_SetItemString(dict, "__module__", modulename) != 0)
- goto failure;
- }
- if (PyTuple_Check(base)) {
- bases = base;
- /* INCREF as we create a new ref in the else branch */
- Py_INCREF(bases);
- } else {
- bases = PyTuple_Pack(1, base);
- if (bases == NULL)
- goto failure;
- }
- /* Create a real new-style class. */
- result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
- dot+1, bases, dict);
+ char *dot;
+ PyObject *modulename = NULL;
+ PyObject *classname = NULL;
+ PyObject *mydict = NULL;
+ PyObject *bases = NULL;
+ PyObject *result = NULL;
+ dot = strrchr(name, '.');
+ if (dot == NULL) {
+ PyErr_SetString(PyExc_SystemError,
+ "PyErr_NewException: name must be module.class");
+ return NULL;
+ }
+ if (base == NULL)
+ base = PyExc_Exception;
+ if (dict == NULL) {
+ dict = mydict = PyDict_New();
+ if (dict == NULL)
+ goto failure;
+ }
+ if (PyDict_GetItemString(dict, "__module__") == NULL) {
+ modulename = PyString_FromStringAndSize(name,
+ (Py_ssize_t)(dot-name));
+ if (modulename == NULL)
+ goto failure;
+ if (PyDict_SetItemString(dict, "__module__", modulename) != 0)
+ goto failure;
+ }
+ if (PyTuple_Check(base)) {
+ bases = base;
+ /* INCREF as we create a new ref in the else branch */
+ Py_INCREF(bases);
+ } else {
+ bases = PyTuple_Pack(1, base);
+ if (bases == NULL)
+ goto failure;
+ }
+ /* Create a real new-style class. */
+ result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
+ dot+1, bases, dict);
failure:
- Py_XDECREF(bases);
- Py_XDECREF(mydict);
- Py_XDECREF(classname);
- Py_XDECREF(modulename);
- return result;
+ Py_XDECREF(bases);
+ Py_XDECREF(mydict);
+ Py_XDECREF(classname);
+ Py_XDECREF(modulename);
+ return result;
}
+
/* Create an exception with docstring */
PyObject *
PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict)
diff --git a/pypy/module/cpyext/src/pysignals.c b/pypy/module/cpyext/src/pysignals.c
--- a/pypy/module/cpyext/src/pysignals.c
+++ b/pypy/module/cpyext/src/pysignals.c
@@ -17,17 +17,34 @@
PyOS_getsig(int sig)
{
#ifdef SA_RESTART
- /* assume sigaction exists */
- struct sigaction context;
- if (sigaction(sig, NULL, &context) == -1)
- return SIG_ERR;
- return context.sa_handler;
+ /* assume sigaction exists */
+ struct sigaction context;
+ if (sigaction(sig, NULL, &context) == -1)
+ return SIG_ERR;
+ return context.sa_handler;
#else
- PyOS_sighandler_t handler;
- handler = signal(sig, SIG_IGN);
- if (handler != SIG_ERR)
- signal(sig, handler);
- return handler;
+ PyOS_sighandler_t handler;
+/* Special signal handling for the secure CRT in Visual Studio 2005 */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ switch (sig) {
+ /* Only these signals are valid */
+ case SIGINT:
+ case SIGILL:
+ case SIGFPE:
+ case SIGSEGV:
+ case SIGTERM:
+ case SIGBREAK:
+ case SIGABRT:
+ break;
+ /* Don't call signal() with other values or it will assert */
+ default:
+ return SIG_ERR;
+ }
+#endif /* _MSC_VER && _MSC_VER >= 1400 */
+ handler = signal(sig, SIG_IGN);
+ if (handler != SIG_ERR)
+ signal(sig, handler);
+ return handler;
#endif
}
@@ -35,21 +52,21 @@
PyOS_setsig(int sig, PyOS_sighandler_t handler)
{
#ifdef SA_RESTART
- /* assume sigaction exists */
- struct sigaction context, ocontext;
- context.sa_handler = handler;
- sigemptyset(&context.sa_mask);
- context.sa_flags = 0;
- if (sigaction(sig, &context, &ocontext) == -1)
- return SIG_ERR;
- return ocontext.sa_handler;
+ /* assume sigaction exists */
+ struct sigaction context, ocontext;
+ context.sa_handler = handler;
+ sigemptyset(&context.sa_mask);
+ context.sa_flags = 0;
+ if (sigaction(sig, &context, &ocontext) == -1)
+ return SIG_ERR;
+ return ocontext.sa_handler;
#else
- PyOS_sighandler_t oldhandler;
- oldhandler = signal(sig, handler);
+ PyOS_sighandler_t oldhandler;
+ oldhandler = signal(sig, handler);
#ifndef MS_WINDOWS
- /* should check if this exists */
- siginterrupt(sig, 1);
+ /* should check if this exists */
+ siginterrupt(sig, 1);
#endif
- return oldhandler;
+ return oldhandler;
#endif
}
diff --git a/pypy/module/cpyext/src/pythonrun.c b/pypy/module/cpyext/src/pythonrun.c
--- a/pypy/module/cpyext/src/pythonrun.c
+++ b/pypy/module/cpyext/src/pythonrun.c
@@ -9,28 +9,28 @@
void
Py_FatalError(const char *msg)
{
- fprintf(stderr, "Fatal Python error: %s\n", msg);
- fflush(stderr); /* it helps in Windows debug build */
+ fprintf(stderr, "Fatal Python error: %s\n", msg);
+ fflush(stderr); /* it helps in Windows debug build */
#ifdef MS_WINDOWS
- {
- size_t len = strlen(msg);
- WCHAR* buffer;
- size_t i;
+ {
+ size_t len = strlen(msg);
+ WCHAR* buffer;
+ size_t i;
- /* Convert the message to wchar_t. This uses a simple one-to-one
- conversion, assuming that the this error message actually uses ASCII
- only. If this ceases to be true, we will have to convert. */
- buffer = alloca( (len+1) * (sizeof *buffer));
- for( i=0; i<=len; ++i)
- buffer[i] = msg[i];
- OutputDebugStringW(L"Fatal Python error: ");
- OutputDebugStringW(buffer);
- OutputDebugStringW(L"\n");
- }
+ /* Convert the message to wchar_t. This uses a simple one-to-one
+ conversion, assuming that the this error message actually uses ASCII
+ only. If this ceases to be true, we will have to convert. */
+ buffer = alloca( (len+1) * (sizeof *buffer));
+ for( i=0; i<=len; ++i)
+ buffer[i] = msg[i];
+ OutputDebugStringW(L"Fatal Python error: ");
+ OutputDebugStringW(buffer);
+ OutputDebugStringW(L"\n");
+ }
#ifdef _DEBUG
- DebugBreak();
+ DebugBreak();
#endif
#endif /* MS_WINDOWS */
- abort();
+ abort();
}
diff --git a/pypy/module/cpyext/src/stringobject.c b/pypy/module/cpyext/src/stringobject.c
--- a/pypy/module/cpyext/src/stringobject.c
+++ b/pypy/module/cpyext/src/stringobject.c
@@ -4,246 +4,247 @@
PyObject *
PyString_FromFormatV(const char *format, va_list vargs)
{
- va_list count;
- Py_ssize_t n = 0;
- const char* f;
- char *s;
- PyObject* string;
+ va_list count;
+ Py_ssize_t n = 0;
+ const char* f;
+ char *s;
+ PyObject* string;
#ifdef VA_LIST_IS_ARRAY
- Py_MEMCPY(count, vargs, sizeof(va_list));
+ Py_MEMCPY(count, vargs, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(count, vargs);
+ __va_copy(count, vargs);
#else
- count = vargs;
+ count = vargs;
#endif
#endif
- /* step 1: figure out how large a buffer we need */
- for (f = format; *f; f++) {
- if (*f == '%') {
+ /* step 1: figure out how large a buffer we need */
+ for (f = format; *f; f++) {
+ if (*f == '%') {
#ifdef HAVE_LONG_LONG
- int longlongflag = 0;
+ int longlongflag = 0;
#endif
- const char* p = f;
- while (*++f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
- ;
+ const char* p = f;
+ while (*++f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
+ ;
- /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
- * they don't affect the amount of space we reserve.
- */
- if (*f == 'l') {
- if (f[1] == 'd' || f[1] == 'u') {
- ++f;
- }
+ /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
+ * they don't affect the amount of space we reserve.
+ */
+ 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;
- }
+ 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;
- }
+ }
+ else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
+ ++f;
+ }
- switch (*f) {
- case 'c':
- (void)va_arg(count, int);
- /* fall through... */
- case '%':
- n++;
- break;
- case 'd': case 'u': case 'i': case 'x':
- (void) va_arg(count, int);
+ switch (*f) {
+ case 'c':
+ (void)va_arg(count, int);
+ /* fall through... */
+ case '%':
+ n++;
+ break;
+ case 'd': case 'u': case 'i': case 'x':
+ (void) va_arg(count, int);
#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
+ /* 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;
+ /* 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*);
- n += strlen(s);
- break;
- case 'p':
- (void) va_arg(count, int);
- /* maximum 64-bit pointer representation:
- * 0xffffffffffffffff
- * so 19 characters is enough.
- * XXX I count 18 -- what's the extra for?
- */
- n += 19;
- break;
- default:
- /* if we stumble upon an unknown
- formatting code, copy the rest of
- the format string to the output
- string. (we cannot just skip the
- code, since there's no way to know
- what's in the argument list) */
- n += strlen(p);
- goto expand;
- }
- } else
- n++;
- }
+ break;
+ case 's':
+ s = va_arg(count, char*);
+ n += strlen(s);
+ break;
+ case 'p':
+ (void) va_arg(count, int);
+ /* maximum 64-bit pointer representation:
+ * 0xffffffffffffffff
+ * so 19 characters is enough.
+ * XXX I count 18 -- what's the extra for?
+ */
+ n += 19;
+ break;
+ default:
+ /* if we stumble upon an unknown
+ formatting code, copy the rest of
+ the format string to the output
+ string. (we cannot just skip the
+ code, since there's no way to know
+ what's in the argument list) */
+ n += strlen(p);
+ goto expand;
+ }
+ } else
+ n++;
+ }
expand:
- /* step 2: fill the buffer */
- /* Since we've analyzed how much space we need for the worst case,
- use sprintf directly instead of the slower PyOS_snprintf. */
- string = PyString_FromStringAndSize(NULL, n);
- if (!string)
- return NULL;
+ /* step 2: fill the buffer */
+ /* Since we've analyzed how much space we need for the worst case,
+ use sprintf directly instead of the slower PyOS_snprintf. */
+ string = PyString_FromStringAndSize(NULL, n);
+ if (!string)
+ return NULL;
- s = PyString_AsString(string);
+ s = PyString_AsString(string);
- for (f = format; *f; f++) {
- if (*f == '%') {
- const char* p = f++;
- Py_ssize_t i;
- int longflag = 0;
+ for (f = format; *f; f++) {
+ if (*f == '%') {
+ const char* p = f++;
+ Py_ssize_t i;
+ int longflag = 0;
#ifdef HAVE_LONG_LONG
- int longlongflag = 0;
+ int longlongflag = 0;
#endif
- int size_tflag = 0;
- /* parse the width.precision part (we're only
- interested in the precision value, if any) */
- n = 0;
- while (isdigit(Py_CHARMASK(*f)))
- n = (n*10) + *f++ - '0';
- if (*f == '.') {
- f++;
- n = 0;
- while (isdigit(Py_CHARMASK(*f)))
- n = (n*10) + *f++ - '0';
- }
- while (*f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
- f++;
- /* Handle %ld, %lu, %lld and %llu. */
- if (*f == 'l') {
- if (f[1] == 'd' || f[1] == 'u') {
- longflag = 1;
- ++f;
- }
+ int size_tflag = 0;
+ /* parse the width.precision part (we're only
+ interested in the precision value, if any) */
+ n = 0;
+ while (isdigit(Py_CHARMASK(*f)))
+ n = (n*10) + *f++ - '0';
+ if (*f == '.') {
+ f++;
+ n = 0;
+ while (isdigit(Py_CHARMASK(*f)))
+ n = (n*10) + *f++ - '0';
+ }
+ while (*f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
+ 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;
- }
+ else if (f[1] == 'l' &&
+ (f[2] == 'd' || f[2] == 'u')) {
+ longlongflag = 1;
+ f += 2;
+ }
#endif
- }
- /* handle the size_t flag. */
- else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
- size_tflag = 1;
- ++f;
- }
+ }
+ /* handle the size_t flag. */
+ else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
+ size_tflag = 1;
+ ++f;
+ }
- switch (*f) {
- case 'c':
- *s++ = va_arg(vargs, int);
- break;
- case 'd':
- if (longflag)
- sprintf(s, "%ld", va_arg(vargs, long));
+ switch (*f) {
+ case 'c':
+ *s++ = va_arg(vargs, int);
+ break;
+ 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));
+ 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));
- else
- sprintf(s, "%d", va_arg(vargs, int));
- s += strlen(s);
- break;
- case 'u':
- if (longflag)
- sprintf(s, "%lu",
- va_arg(vargs, unsigned long));
+ else if (size_tflag)
+ sprintf(s, "%" PY_FORMAT_SIZE_T "d",
+ va_arg(vargs, Py_ssize_t));
+ else
+ sprintf(s, "%d", va_arg(vargs, int));
+ s += strlen(s);
+ break;
+ case 'u':
+ 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));
+ 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));
- else
- sprintf(s, "%u",
- va_arg(vargs, unsigned int));
- s += strlen(s);
- break;
- case 'i':
- sprintf(s, "%i", va_arg(vargs, int));
- s += strlen(s);
- break;
- case 'x':
- sprintf(s, "%x", va_arg(vargs, int));
- s += strlen(s);
- break;
- case 's':
- p = va_arg(vargs, char*);
- i = strlen(p);
- if (n > 0 && i > n)
- i = n;
- Py_MEMCPY(s, p, i);
- s += i;
- break;
- case 'p':
- sprintf(s, "%p", va_arg(vargs, void*));
- /* %p is ill-defined: ensure leading 0x. */
- if (s[1] == 'X')
- s[1] = 'x';
- else if (s[1] != 'x') {
- memmove(s+2, s, strlen(s)+1);
- s[0] = '0';
- s[1] = 'x';
- }
- s += strlen(s);
- break;
- case '%':
- *s++ = '%';
- break;
- default:
- strcpy(s, p);
- s += strlen(s);
- goto end;
- }
- } else
- *s++ = *f;
- }
+ else if (size_tflag)
+ sprintf(s, "%" PY_FORMAT_SIZE_T "u",
+ va_arg(vargs, size_t));
+ else
+ sprintf(s, "%u",
+ va_arg(vargs, unsigned int));
+ s += strlen(s);
+ break;
+ case 'i':
+ sprintf(s, "%i", va_arg(vargs, int));
+ s += strlen(s);
+ break;
+ case 'x':
+ sprintf(s, "%x", va_arg(vargs, int));
+ s += strlen(s);
+ break;
+ case 's':
+ p = va_arg(vargs, char*);
+ i = strlen(p);
+ if (n > 0 && i > n)
+ i = n;
+ Py_MEMCPY(s, p, i);
+ s += i;
+ break;
+ case 'p':
+ sprintf(s, "%p", va_arg(vargs, void*));
+ /* %p is ill-defined: ensure leading 0x. */
+ if (s[1] == 'X')
+ s[1] = 'x';
+ else if (s[1] != 'x') {
+ memmove(s+2, s, strlen(s)+1);
+ s[0] = '0';
+ s[1] = 'x';
+ }
+ s += strlen(s);
+ break;
+ case '%':
+ *s++ = '%';
+ break;
+ default:
+ strcpy(s, p);
+ s += strlen(s);
+ goto end;
+ }
+ } else
+ *s++ = *f;
+ }
end:
- _PyString_Resize(&string, s - PyString_AS_STRING(string));
- return string;
+ if (_PyString_Resize(&string, s - PyString_AS_STRING(string)))
+ return NULL;
+ return string;
}
PyObject *
PyString_FromFormat(const char *format, ...)
{
- PyObject* ret;
- va_list vargs;
+ PyObject* ret;
+ va_list vargs;
#ifdef HAVE_STDARG_PROTOTYPES
- va_start(vargs, format);
+ va_start(vargs, format);
#else
- va_start(vargs);
+ va_start(vargs);
#endif
- ret = PyString_FromFormatV(format, vargs);
- va_end(vargs);
- return ret;
+ ret = PyString_FromFormatV(format, vargs);
+ va_end(vargs);
+ return ret;
}
diff --git a/pypy/module/cpyext/src/structseq.c b/pypy/module/cpyext/src/structseq.c
--- a/pypy/module/cpyext/src/structseq.c
+++ b/pypy/module/cpyext/src/structseq.c
@@ -175,32 +175,33 @@
if (min_len != max_len) {
if (len < min_len) {
PyErr_Format(PyExc_TypeError,
- "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
- type->tp_name, min_len, len);
- Py_DECREF(arg);
- return NULL;
+ "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
+ type->tp_name, min_len, len);
+ Py_DECREF(arg);
+ return NULL;
}
if (len > max_len) {
PyErr_Format(PyExc_TypeError,
- "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
- type->tp_name, max_len, len);
- Py_DECREF(arg);
- return NULL;
+ "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
+ type->tp_name, max_len, len);
+ Py_DECREF(arg);
+ return NULL;
}
}
else {
if (len != min_len) {
PyErr_Format(PyExc_TypeError,
- "%.500s() takes a %zd-sequence (%zd-sequence given)",
- type->tp_name, min_len, len);
- Py_DECREF(arg);
- return NULL;
+ "%.500s() takes a %zd-sequence (%zd-sequence given)",
+ type->tp_name, min_len, len);
+ Py_DECREF(arg);
+ return NULL;
}
}
res = (PyStructSequence*) PyStructSequence_New(type);
if (res == NULL) {
+ Py_DECREF(arg);
return NULL;
}
for (i = 0; i < len; ++i) {
diff --git a/pypy/module/cpyext/src/sysmodule.c b/pypy/module/cpyext/src/sysmodule.c
--- a/pypy/module/cpyext/src/sysmodule.c
+++ b/pypy/module/cpyext/src/sysmodule.c
@@ -100,4 +100,3 @@
sys_write("stderr", stderr, format, va);
va_end(va);
}
-
diff --git a/pypy/module/cpyext/src/varargwrapper.c b/pypy/module/cpyext/src/varargwrapper.c
--- a/pypy/module/cpyext/src/varargwrapper.c
+++ b/pypy/module/cpyext/src/varargwrapper.c
@@ -1,21 +1,25 @@
#include <Python.h>
#include <stdarg.h>
-PyObject * PyTuple_Pack(Py_ssize_t size, ...)
+PyObject *
+PyTuple_Pack(Py_ssize_t n, ...)
{
- va_list ap;
- PyObject *cur, *tuple;
- int i;
+ Py_ssize_t i;
+ PyObject *o;
+ PyObject *result;
+ va_list vargs;
- tuple = PyTuple_New(size);
- va_start(ap, size);
- for (i = 0; i < size; i++) {
- cur = va_arg(ap, PyObject*);
- Py_INCREF(cur);
- if (PyTuple_SetItem(tuple, i, cur) < 0)
+ va_start(vargs, n);
+ result = PyTuple_New(n);
+ if (result == NULL)
+ return NULL;
+ for (i = 0; i < n; i++) {
+ o = va_arg(vargs, PyObject *);
+ Py_INCREF(o);
+ if (PyTuple_SetItem(result, i, o) < 0)
return NULL;
}
- va_end(ap);
- return tuple;
+ va_end(vargs);
+ return result;
}
diff --git a/pypy/module/cpyext/structmember.py b/pypy/module/cpyext/structmember.py
--- a/pypy/module/cpyext/structmember.py
+++ b/pypy/module/cpyext/structmember.py
@@ -10,7 +10,7 @@
PyString_FromString, PyString_FromStringAndSize)
from pypy.module.cpyext.floatobject import PyFloat_AsDouble
from pypy.module.cpyext.longobject import (
- PyLong_AsLongLong, PyLong_AsUnsignedLongLong)
+ PyLong_AsLongLong, PyLong_AsUnsignedLongLong, PyLong_AsSsize_t)
from pypy.module.cpyext.typeobjectdefs import PyMemberDef
from pypy.rlib.unroll import unrolling_iterable
@@ -28,6 +28,7 @@
(T_DOUBLE, rffi.DOUBLE, PyFloat_AsDouble),
(T_LONGLONG, rffi.LONGLONG, PyLong_AsLongLong),
(T_ULONGLONG, rffi.ULONGLONG, PyLong_AsUnsignedLongLong),
+ (T_PYSSIZET, rffi.SSIZE_T, PyLong_AsSsize_t),
])
diff --git a/pypy/module/cpyext/structmemberdefs.py b/pypy/module/cpyext/structmemberdefs.py
--- a/pypy/module/cpyext/structmemberdefs.py
+++ b/pypy/module/cpyext/structmemberdefs.py
@@ -18,6 +18,7 @@
T_OBJECT_EX = 16
T_LONGLONG = 17
T_ULONGLONG = 18
+T_PYSSIZET = 19
READONLY = RO = 1
READ_RESTRICTED = 2
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -1405,13 +1405,6 @@
"""
raise NotImplementedError
- at cpython_api([Py_ssize_t], PyObject)
-def PyLong_FromSsize_t(space, v):
- """Return a new PyLongObject object from a C Py_ssize_t, or
- NULL on failure.
- """
- raise NotImplementedError
-
@cpython_api([rffi.SIZE_T], PyObject)
def PyLong_FromSize_t(space, v):
"""Return a new PyLongObject object from a C size_t, or
@@ -1431,14 +1424,6 @@
changes in your code for properly supporting 64-bit systems."""
raise NotImplementedError
- at cpython_api([PyObject], Py_ssize_t, error=-1)
-def PyLong_AsSsize_t(space, pylong):
- """Return a C Py_ssize_t representation of the contents of pylong. If
- pylong is greater than PY_SSIZE_T_MAX, an OverflowError is raised
- and -1 will be returned.
- """
- raise NotImplementedError
-
@cpython_api([PyObject, rffi.CCHARP], rffi.INT_real, error=-1)
def PyMapping_DelItemString(space, o, key):
"""Remove the mapping for object key from the object o. Return -1 on
@@ -1980,35 +1965,6 @@
changes in your code for properly supporting 64-bit systems."""
raise NotImplementedError
- at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, rffi.INTP], PyObject)
-def PyUnicode_DecodeUTF32(space, s, size, errors, byteorder):
- """Decode length bytes from a UTF-32 encoded buffer string and return the
- corresponding Unicode object. errors (if non-NULL) defines the error
- handling. It defaults to "strict".
-
- If byteorder is non-NULL, the decoder starts decoding using the given byte
- order:
-
- *byteorder == -1: little endian
- *byteorder == 0: native order
- *byteorder == 1: big endian
-
- If *byteorder is zero, and the first four bytes of the input data are a
- byte order mark (BOM), the decoder switches to this byte order and the BOM is
- not copied into the resulting Unicode string. If *byteorder is -1 or
- 1, any byte order mark is copied to the output.
-
- After completion, *byteorder is set to the current byte order at the end
- of input data.
-
- In a narrow build codepoints outside the BMP will be decoded as surrogate pairs.
-
- If byteorder is NULL, the codec starts in native order mode.
-
- Return NULL if an exception was raised by the codec.
- """
- raise NotImplementedError
-
@cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, rffi.INTP, Py_ssize_t], PyObject)
def PyUnicode_DecodeUTF32Stateful(space, s, size, errors, byteorder, consumed):
"""If consumed is NULL, behave like PyUnicode_DecodeUTF32(). If
diff --git a/pypy/module/cpyext/test/_sre.c b/pypy/module/cpyext/test/_sre.c
--- a/pypy/module/cpyext/test/_sre.c
+++ b/pypy/module/cpyext/test/_sre.c
@@ -81,9 +81,6 @@
#define PyObject_DEL(op) PyMem_DEL((op))
#endif
-#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
-#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
-
/* -------------------------------------------------------------------- */
#if defined(_MSC_VER)
@@ -1689,7 +1686,7 @@
if (PyUnicode_Check(string)) {
/* unicode strings doesn't always support the buffer interface */
ptr = (void*) PyUnicode_AS_DATA(string);
- bytes = PyUnicode_GET_DATA_SIZE(string);
+ /* bytes = PyUnicode_GET_DATA_SIZE(string); */
size = PyUnicode_GET_SIZE(string);
charsize = sizeof(Py_UNICODE);
@@ -2601,46 +2598,22 @@
{NULL, NULL}
};
-static PyObject*
-pattern_getattr(PatternObject* self, char* name)
-{
- PyObject* res;
-
- res = Py_FindMethod(pattern_methods, (PyObject*) self, name);
-
- if (res)
- return res;
-
- PyErr_Clear();
-
- /* attributes */
- if (!strcmp(name, "pattern")) {
- Py_INCREF(self->pattern);
- return self->pattern;
- }
-
- if (!strcmp(name, "flags"))
- return Py_BuildValue("i", self->flags);
-
- if (!strcmp(name, "groups"))
- return Py_BuildValue("i", self->groups);
-
- if (!strcmp(name, "groupindex") && self->groupindex) {
- Py_INCREF(self->groupindex);
- return self->groupindex;
- }
-
- PyErr_SetString(PyExc_AttributeError, name);
- return NULL;
-}
+#define PAT_OFF(x) offsetof(PatternObject, x)
+static PyMemberDef pattern_members[] = {
+ {"pattern", T_OBJECT, PAT_OFF(pattern), READONLY},
+ {"flags", T_INT, PAT_OFF(flags), READONLY},
+ {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY},
+ {"groupindex", T_OBJECT, PAT_OFF(groupindex), READONLY},
+ {NULL} /* Sentinel */
+};
statichere PyTypeObject Pattern_Type = {
PyObject_HEAD_INIT(NULL)
0, "_" SRE_MODULE ".SRE_Pattern",
sizeof(PatternObject), sizeof(SRE_CODE),
(destructor)pattern_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc)pattern_getattr, /*tp_getattr*/
+ 0, /* tp_print */
+ 0, /* tp_getattrn */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
@@ -2653,12 +2626,16 @@
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
pattern_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ pattern_methods, /* tp_methods */
+ pattern_members, /* tp_members */
};
static int _validate(PatternObject *self); /* Forward */
@@ -2767,7 +2744,7 @@
#if defined(VVERBOSE)
#define VTRACE(v) printf v
#else
-#define VTRACE(v)
+#define VTRACE(v) do {} while(0) /* do nothing */
#endif
/* Report failure */
@@ -2970,13 +2947,13 @@
<INFO> <1=skip> <2=flags> <3=min> <4=max>;
If SRE_INFO_PREFIX or SRE_INFO_CHARSET is in the flags,
more follows. */
- SRE_CODE flags, min, max, i;
+ SRE_CODE flags, i;
SRE_CODE *newcode;
GET_SKIP;
newcode = code+skip-1;
GET_ARG; flags = arg;
- GET_ARG; min = arg;
- GET_ARG; max = arg;
+ GET_ARG; /* min */
+ GET_ARG; /* max */
/* Check that only valid flags are present */
if ((flags & ~(SRE_INFO_PREFIX |
SRE_INFO_LITERAL |
@@ -2992,9 +2969,9 @@
FAIL;
/* Validate the prefix */
if (flags & SRE_INFO_PREFIX) {
- SRE_CODE prefix_len, prefix_skip;
+ SRE_CODE prefix_len;
GET_ARG; prefix_len = arg;
- GET_ARG; prefix_skip = arg;
+ GET_ARG; /* prefix skip */
/* Here comes the prefix string */
if (code+prefix_len < code || code+prefix_len > newcode)
FAIL;
@@ -3565,7 +3542,7 @@
#endif
}
-static PyMethodDef match_methods[] = {
+static struct PyMethodDef match_methods[] = {
{"group", (PyCFunction) match_group, METH_VARARGS},
{"start", (PyCFunction) match_start, METH_VARARGS},
{"end", (PyCFunction) match_end, METH_VARARGS},
@@ -3578,80 +3555,90 @@
{NULL, NULL}
};
-static PyObject*
-match_getattr(MatchObject* self, char* name)
+static PyObject *
+match_lastindex_get(MatchObject *self)
{
- PyObject* res;
-
- res = Py_FindMethod(match_methods, (PyObject*) self, name);
- if (res)
- return res;
-
- PyErr_Clear();
-
- if (!strcmp(name, "lastindex")) {
- if (self->lastindex >= 0)
- return Py_BuildValue("i", self->lastindex);
- Py_INCREF(Py_None);
- return Py_None;
+ if (self->lastindex >= 0)
+ return Py_BuildValue("i", self->lastindex);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+match_lastgroup_get(MatchObject *self)
+{
+ if (self->pattern->indexgroup && self->lastindex >= 0) {
+ PyObject* result = PySequence_GetItem(
+ self->pattern->indexgroup, self->lastindex
+ );
+ if (result)
+ return result;
+ PyErr_Clear();
}
-
- if (!strcmp(name, "lastgroup")) {
- if (self->pattern->indexgroup && self->lastindex >= 0) {
- PyObject* result = PySequence_GetItem(
- self->pattern->indexgroup, self->lastindex
- );
- if (result)
- return result;
- PyErr_Clear();
- }
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- if (!strcmp(name, "string")) {
- if (self->string) {
- Py_INCREF(self->string);
- return self->string;
- } else {
- Py_INCREF(Py_None);
- return Py_None;
- }
- }
-
- if (!strcmp(name, "regs")) {
- if (self->regs) {
- Py_INCREF(self->regs);
- return self->regs;
- } else
- return match_regs(self);
- }
-
- if (!strcmp(name, "re")) {
- Py_INCREF(self->pattern);
- return (PyObject*) self->pattern;
- }
-
- if (!strcmp(name, "pos"))
- return Py_BuildValue("i", self->pos);
-
- if (!strcmp(name, "endpos"))
- return Py_BuildValue("i", self->endpos);
-
- PyErr_SetString(PyExc_AttributeError, name);
- return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
}
+static PyObject *
+match_regs_get(MatchObject *self)
+{
+ if (self->regs) {
+ Py_INCREF(self->regs);
+ return self->regs;
+ } else
+ return match_regs(self);
+}
+
+static PyGetSetDef match_getset[] = {
+ {"lastindex", (getter)match_lastindex_get, (setter)NULL},
+ {"lastgroup", (getter)match_lastgroup_get, (setter)NULL},
+ {"regs", (getter)match_regs_get, (setter)NULL},
+ {NULL}
+};
+
+#define MATCH_OFF(x) offsetof(MatchObject, x)
+static PyMemberDef match_members[] = {
+ {"string", T_OBJECT, MATCH_OFF(string), READONLY},
+ {"re", T_OBJECT, MATCH_OFF(pattern), READONLY},
+ {"pos", T_PYSSIZET, MATCH_OFF(pos), READONLY},
+ {"endpos", T_PYSSIZET, MATCH_OFF(endpos), READONLY},
+ {NULL}
+};
+
+
/* FIXME: implement setattr("string", None) as a special case (to
detach the associated string, if any */
-statichere PyTypeObject Match_Type = {
- PyObject_HEAD_INIT(NULL)
- 0, "_" SRE_MODULE ".SRE_Match",
+static PyTypeObject Match_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "_" SRE_MODULE ".SRE_Match",
sizeof(MatchObject), sizeof(Py_ssize_t),
- (destructor)match_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc)match_getattr /*tp_getattr*/
+ (destructor)match_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT,
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ match_methods, /* tp_methods */
+ match_members, /* tp_members */
+ match_getset, /* tp_getset */
};
static PyObject*
@@ -3800,34 +3787,42 @@
{NULL, NULL}
};
-static PyObject*
-scanner_getattr(ScannerObject* self, char* name)
-{
- PyObject* res;
-
- res = Py_FindMethod(scanner_methods, (PyObject*) self, name);
- if (res)
- return res;
-
- PyErr_Clear();
-
- /* attributes */
- if (!strcmp(name, "pattern")) {
- Py_INCREF(self->pattern);
- return self->pattern;
- }
-
- PyErr_SetString(PyExc_AttributeError, name);
- return NULL;
-}
+#define SCAN_OFF(x) offsetof(ScannerObject, x)
+static PyMemberDef scanner_members[] = {
+ {"pattern", T_OBJECT, SCAN_OFF(pattern), READONLY},
+ {NULL} /* Sentinel */
+};
statichere PyTypeObject Scanner_Type = {
PyObject_HEAD_INIT(NULL)
0, "_" SRE_MODULE ".SRE_Scanner",
sizeof(ScannerObject), 0,
(destructor)scanner_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc)scanner_getattr, /*tp_getattr*/
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ scanner_methods, /* tp_methods */
+ scanner_members, /* tp_members */
+ 0, /* tp_getset */
};
static PyObject*
@@ -3879,8 +3874,9 @@
PyObject* x;
/* Patch object types */
- Pattern_Type.ob_type = Match_Type.ob_type =
- Scanner_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&Pattern_Type) || PyType_Ready(&Match_Type) ||
+ PyType_Ready(&Scanner_Type))
+ return;
m = Py_InitModule("_" SRE_MODULE, _functions);
if (m == NULL)
diff --git a/pypy/module/cpyext/test/array.c b/pypy/module/cpyext/test/array.c
--- a/pypy/module/cpyext/test/array.c
+++ b/pypy/module/cpyext/test/array.c
@@ -11,13 +11,10 @@
#include <stddef.h>
#else /* !STDC_HEADERS */
#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h> /* For size_t */
+#include <sys/types.h> /* For size_t */
#endif /* HAVE_SYS_TYPES_H */
#endif /* !STDC_HEADERS */
-#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
-#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
-
struct arrayobject; /* Forward */
/* All possible arraydescr values are defined in the vector "descriptors"
@@ -25,18 +22,18 @@
* functions aren't visible yet.
*/
struct arraydescr {
- int typecode;
- int itemsize;
- PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
- int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
+ int typecode;
+ int itemsize;
+ PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
+ int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
};
typedef struct arrayobject {
- PyObject_VAR_HEAD
- char *ob_item;
- Py_ssize_t allocated;
- struct arraydescr *ob_descr;
- PyObject *weakreflist; /* List of weak references */
+ PyObject_VAR_HEAD
+ char *ob_item;
+ Py_ssize_t allocated;
+ struct arraydescr *ob_descr;
+ PyObject *weakreflist; /* List of weak references */
} arrayobject;
static PyTypeObject Arraytype;
@@ -47,49 +44,49 @@
static int
array_resize(arrayobject *self, Py_ssize_t newsize)
{
- char *items;
- size_t _new_size;
+ char *items;
+ size_t _new_size;
- /* Bypass realloc() when a previous overallocation is large enough
- to accommodate the newsize. If the newsize is 16 smaller than the
- current size, then proceed with the realloc() to shrink the list.
- */
+ /* Bypass realloc() when a previous overallocation is large enough
+ to accommodate the newsize. If the newsize is 16 smaller than the
+ current size, then proceed with the realloc() to shrink the list.
+ */
- if (self->allocated >= newsize &&
- Py_SIZE(self) < newsize + 16 &&
- self->ob_item != NULL) {
- Py_SIZE(self) = newsize;
- return 0;
- }
+ if (self->allocated >= newsize &&
+ Py_SIZE(self) < newsize + 16 &&
+ self->ob_item != NULL) {
+ Py_SIZE(self) = newsize;
+ return 0;
+ }
- /* This over-allocates proportional to the array size, making room
- * for additional growth. The over-allocation is mild, but is
- * enough to give linear-time amortized behavior over a long
- * sequence of appends() in the presence of a poorly-performing
- * system realloc().
- * The growth pattern is: 0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ...
- * Note, the pattern starts out the same as for lists but then
- * grows at a smaller rate so that larger arrays only overallocate
- * by about 1/16th -- this is done because arrays are presumed to be more
- * memory critical.
- */
+ /* This over-allocates proportional to the array size, making room
+ * for additional growth. The over-allocation is mild, but is
+ * enough to give linear-time amortized behavior over a long
+ * sequence of appends() in the presence of a poorly-performing
+ * system realloc().
+ * The growth pattern is: 0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ...
+ * Note, the pattern starts out the same as for lists but then
+ * grows at a smaller rate so that larger arrays only overallocate
+ * by about 1/16th -- this is done because arrays are presumed to be more
+ * memory critical.
+ */
- _new_size = (newsize >> 4) + (Py_SIZE(self) < 8 ? 3 : 7) + newsize;
- items = self->ob_item;
- /* XXX The following multiplication and division does not optimize away
- like it does for lists since the size is not known at compile time */
- if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize))
- PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize));
- else
- items = NULL;
- if (items == NULL) {
- PyErr_NoMemory();
- return -1;
- }
- self->ob_item = items;
- Py_SIZE(self) = newsize;
- self->allocated = _new_size;
- return 0;
+ _new_size = (newsize >> 4) + (Py_SIZE(self) < 8 ? 3 : 7) + newsize;
+ items = self->ob_item;
+ /* XXX The following multiplication and division does not optimize away
+ like it does for lists since the size is not known at compile time */
+ if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize))
+ PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize));
+ else
+ items = NULL;
+ if (items == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->ob_item = items;
+ Py_SIZE(self) = newsize;
+ self->allocated = _new_size;
+ return 0;
}
/****************************************************************************
@@ -107,308 +104,308 @@
static PyObject *
c_getitem(arrayobject *ap, Py_ssize_t i)
{
- return PyString_FromStringAndSize(&((char *)ap->ob_item)[i], 1);
+ return PyString_FromStringAndSize(&((char *)ap->ob_item)[i], 1);
}
static int
c_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- char x;
- if (!PyArg_Parse(v, "c;array item must be char", &x))
- return -1;
- if (i >= 0)
- ((char *)ap->ob_item)[i] = x;
- return 0;
+ char x;
+ if (!PyArg_Parse(v, "c;array item must be char", &x))
+ return -1;
+ if (i >= 0)
+ ((char *)ap->ob_item)[i] = x;
+ return 0;
}
static PyObject *
b_getitem(arrayobject *ap, Py_ssize_t i)
{
- long x = ((char *)ap->ob_item)[i];
- if (x >= 128)
- x -= 256;
- return PyInt_FromLong(x);
+ long x = ((char *)ap->ob_item)[i];
+ if (x >= 128)
+ x -= 256;
+ return PyInt_FromLong(x);
}
static int
b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- short x;
- /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore
- must use the next size up that is signed ('h') and manually do
- the overflow checking */
- if (!PyArg_Parse(v, "h;array item must be integer", &x))
- return -1;
- else if (x < -128) {
- PyErr_SetString(PyExc_OverflowError,
- "signed char is less than minimum");
- return -1;
- }
- else if (x > 127) {
- PyErr_SetString(PyExc_OverflowError,
- "signed char is greater than maximum");
- return -1;
- }
- if (i >= 0)
- ((char *)ap->ob_item)[i] = (char)x;
- return 0;
+ short x;
+ /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore
+ must use the next size up that is signed ('h') and manually do
+ the overflow checking */
+ if (!PyArg_Parse(v, "h;array item must be integer", &x))
+ return -1;
+ else if (x < -128) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed char is less than minimum");
+ return -1;
+ }
+ else if (x > 127) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed char is greater than maximum");
+ return -1;
+ }
+ if (i >= 0)
+ ((char *)ap->ob_item)[i] = (char)x;
+ return 0;
}
static PyObject *
BB_getitem(arrayobject *ap, Py_ssize_t i)
{
- long x = ((unsigned char *)ap->ob_item)[i];
- return PyInt_FromLong(x);
+ long x = ((unsigned char *)ap->ob_item)[i];
+ return PyInt_FromLong(x);
}
static int
BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- unsigned char x;
- /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */
- if (!PyArg_Parse(v, "b;array item must be integer", &x))
- return -1;
- if (i >= 0)
- ((char *)ap->ob_item)[i] = x;
- return 0;
+ unsigned char x;
+ /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */
+ if (!PyArg_Parse(v, "b;array item must be integer", &x))
+ return -1;
+ if (i >= 0)
+ ((char *)ap->ob_item)[i] = x;
+ return 0;
}
#ifdef Py_USING_UNICODE
static PyObject *
u_getitem(arrayobject *ap, Py_ssize_t i)
{
- return PyUnicode_FromUnicode(&((Py_UNICODE *) ap->ob_item)[i], 1);
+ return PyUnicode_FromUnicode(&((Py_UNICODE *) ap->ob_item)[i], 1);
}
static int
u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- Py_UNICODE *p;
- Py_ssize_t len;
+ Py_UNICODE *p;
+ Py_ssize_t len;
- if (!PyArg_Parse(v, "u#;array item must be unicode character", &p, &len))
- return -1;
- if (len != 1) {
- PyErr_SetString(PyExc_TypeError,
- "array item must be unicode character");
- return -1;
- }
- if (i >= 0)
- ((Py_UNICODE *)ap->ob_item)[i] = p[0];
- return 0;
+ if (!PyArg_Parse(v, "u#;array item must be unicode character", &p, &len))
+ return -1;
+ if (len != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "array item must be unicode character");
+ return -1;
+ }
+ if (i >= 0)
+ ((Py_UNICODE *)ap->ob_item)[i] = p[0];
+ return 0;
}
#endif
static PyObject *
h_getitem(arrayobject *ap, Py_ssize_t i)
{
- return PyInt_FromLong((long) ((short *)ap->ob_item)[i]);
+ return PyInt_FromLong((long) ((short *)ap->ob_item)[i]);
}
static int
h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- short x;
- /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */
- if (!PyArg_Parse(v, "h;array item must be integer", &x))
- return -1;
- if (i >= 0)
- ((short *)ap->ob_item)[i] = x;
- return 0;
+ short x;
+ /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */
+ if (!PyArg_Parse(v, "h;array item must be integer", &x))
+ return -1;
+ if (i >= 0)
+ ((short *)ap->ob_item)[i] = x;
+ return 0;
}
static PyObject *
HH_getitem(arrayobject *ap, Py_ssize_t i)
{
- return PyInt_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
+ return PyInt_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
}
static int
HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- int x;
- /* PyArg_Parse's 'h' formatter is for a signed short, therefore
- must use the next size up and manually do the overflow checking */
- if (!PyArg_Parse(v, "i;array item must be integer", &x))
- return -1;
- else if (x < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned short is less than minimum");
- return -1;
- }
- else if (x > USHRT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned short is greater than maximum");
- return -1;
- }
- if (i >= 0)
- ((short *)ap->ob_item)[i] = (short)x;
- return 0;
+ int x;
+ /* PyArg_Parse's 'h' formatter is for a signed short, therefore
+ must use the next size up and manually do the overflow checking */
+ if (!PyArg_Parse(v, "i;array item must be integer", &x))
+ return -1;
+ else if (x < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned short is less than minimum");
+ return -1;
+ }
+ else if (x > USHRT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned short is greater than maximum");
+ return -1;
+ }
+ if (i >= 0)
+ ((short *)ap->ob_item)[i] = (short)x;
+ return 0;
}
static PyObject *
i_getitem(arrayobject *ap, Py_ssize_t i)
{
- return PyInt_FromLong((long) ((int *)ap->ob_item)[i]);
+ return PyInt_FromLong((long) ((int *)ap->ob_item)[i]);
}
static int
i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- int x;
- /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */
- if (!PyArg_Parse(v, "i;array item must be integer", &x))
- return -1;
- if (i >= 0)
- ((int *)ap->ob_item)[i] = x;
- return 0;
+ int x;
+ /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */
+ if (!PyArg_Parse(v, "i;array item must be integer", &x))
+ return -1;
+ if (i >= 0)
+ ((int *)ap->ob_item)[i] = x;
+ return 0;
}
static PyObject *
II_getitem(arrayobject *ap, Py_ssize_t i)
{
- return PyLong_FromUnsignedLong(
- (unsigned long) ((unsigned int *)ap->ob_item)[i]);
+ return PyLong_FromUnsignedLong(
+ (unsigned long) ((unsigned int *)ap->ob_item)[i]);
}
static int
II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- unsigned long x;
- if (PyLong_Check(v)) {
- x = PyLong_AsUnsignedLong(v);
- if (x == (unsigned long) -1 && PyErr_Occurred())
- return -1;
- }
- else {
- long y;
- if (!PyArg_Parse(v, "l;array item must be integer", &y))
- return -1;
- if (y < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned int is less than minimum");
- return -1;
- }
- x = (unsigned long)y;
+ unsigned long x;
+ if (PyLong_Check(v)) {
+ x = PyLong_AsUnsignedLong(v);
+ if (x == (unsigned long) -1 && PyErr_Occurred())
+ return -1;
+ }
+ else {
+ long y;
+ if (!PyArg_Parse(v, "l;array item must be integer", &y))
+ return -1;
+ if (y < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned int is less than minimum");
+ return -1;
+ }
+ x = (unsigned long)y;
- }
- if (x > UINT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned int is greater than maximum");
- return -1;
- }
+ }
+ if (x > UINT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned int is greater than maximum");
+ return -1;
+ }
- if (i >= 0)
- ((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
- return 0;
+ if (i >= 0)
+ ((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
+ return 0;
}
static PyObject *
l_getitem(arrayobject *ap, Py_ssize_t i)
{
- return PyInt_FromLong(((long *)ap->ob_item)[i]);
+ return PyInt_FromLong(((long *)ap->ob_item)[i]);
}
static int
l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- long x;
- if (!PyArg_Parse(v, "l;array item must be integer", &x))
- return -1;
- if (i >= 0)
- ((long *)ap->ob_item)[i] = x;
- return 0;
+ long x;
+ if (!PyArg_Parse(v, "l;array item must be integer", &x))
+ return -1;
+ if (i >= 0)
+ ((long *)ap->ob_item)[i] = x;
+ return 0;
}
static PyObject *
LL_getitem(arrayobject *ap, Py_ssize_t i)
{
- return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
+ return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
}
static int
LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- unsigned long x;
- if (PyLong_Check(v)) {
- x = PyLong_AsUnsignedLong(v);
- if (x == (unsigned long) -1 && PyErr_Occurred())
- return -1;
- }
- else {
- long y;
- if (!PyArg_Parse(v, "l;array item must be integer", &y))
- return -1;
- if (y < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned long is less than minimum");
- return -1;
- }
- x = (unsigned long)y;
+ unsigned long x;
+ if (PyLong_Check(v)) {
+ x = PyLong_AsUnsignedLong(v);
+ if (x == (unsigned long) -1 && PyErr_Occurred())
+ return -1;
+ }
+ else {
+ long y;
+ if (!PyArg_Parse(v, "l;array item must be integer", &y))
+ return -1;
+ if (y < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned long is less than minimum");
+ return -1;
+ }
+ x = (unsigned long)y;
- }
- if (x > ULONG_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned long is greater than maximum");
- return -1;
- }
+ }
+ if (x > ULONG_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned long is greater than maximum");
+ return -1;
+ }
- if (i >= 0)
- ((unsigned long *)ap->ob_item)[i] = x;
- return 0;
+ if (i >= 0)
+ ((unsigned long *)ap->ob_item)[i] = x;
+ return 0;
}
static PyObject *
f_getitem(arrayobject *ap, Py_ssize_t i)
{
- return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
+ return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
}
static int
f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- float x;
- if (!PyArg_Parse(v, "f;array item must be float", &x))
- return -1;
- if (i >= 0)
- ((float *)ap->ob_item)[i] = x;
- return 0;
+ float x;
+ if (!PyArg_Parse(v, "f;array item must be float", &x))
+ return -1;
+ if (i >= 0)
+ ((float *)ap->ob_item)[i] = x;
+ return 0;
}
static PyObject *
d_getitem(arrayobject *ap, Py_ssize_t i)
{
- return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
+ return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
}
static int
d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
- double x;
- if (!PyArg_Parse(v, "d;array item must be float", &x))
- return -1;
- if (i >= 0)
- ((double *)ap->ob_item)[i] = x;
- return 0;
+ double x;
+ if (!PyArg_Parse(v, "d;array item must be float", &x))
+ return -1;
+ if (i >= 0)
+ ((double *)ap->ob_item)[i] = x;
+ return 0;
}
/* Description of types */
static struct arraydescr descriptors[] = {
- {'c', sizeof(char), c_getitem, c_setitem},
- {'b', sizeof(char), b_getitem, b_setitem},
- {'B', sizeof(char), BB_getitem, BB_setitem},
+ {'c', sizeof(char), c_getitem, c_setitem},
+ {'b', sizeof(char), b_getitem, b_setitem},
+ {'B', sizeof(char), BB_getitem, BB_setitem},
#ifdef Py_USING_UNICODE
- {'u', sizeof(Py_UNICODE), u_getitem, u_setitem},
+ {'u', sizeof(Py_UNICODE), u_getitem, u_setitem},
#endif
- {'h', sizeof(short), h_getitem, h_setitem},
- {'H', sizeof(short), HH_getitem, HH_setitem},
- {'i', sizeof(int), i_getitem, i_setitem},
- {'I', sizeof(int), II_getitem, II_setitem},
- {'l', sizeof(long), l_getitem, l_setitem},
- {'L', sizeof(long), LL_getitem, LL_setitem},
- {'f', sizeof(float), f_getitem, f_setitem},
- {'d', sizeof(double), d_getitem, d_setitem},
- {'\0', 0, 0, 0} /* Sentinel */
+ {'h', sizeof(short), h_getitem, h_setitem},
+ {'H', sizeof(short), HH_getitem, HH_setitem},
+ {'i', sizeof(int), i_getitem, i_setitem},
+ {'I', sizeof(int), II_getitem, II_setitem},
+ {'l', sizeof(long), l_getitem, l_setitem},
+ {'L', sizeof(long), LL_getitem, LL_setitem},
+ {'f', sizeof(float), f_getitem, f_setitem},
+ {'d', sizeof(double), d_getitem, d_setitem},
+ {'\0', 0, 0, 0} /* Sentinel */
};
/****************************************************************************
@@ -418,78 +415,78 @@
static PyObject *
newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
{
- arrayobject *op;
- size_t nbytes;
+ arrayobject *op;
+ size_t nbytes;
- if (size < 0) {
- PyErr_BadInternalCall();
- return NULL;
- }
+ if (size < 0) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
- nbytes = size * descr->itemsize;
- /* Check for overflow */
- if (nbytes / descr->itemsize != (size_t)size) {
- return PyErr_NoMemory();
- }
- op = (arrayobject *) type->tp_alloc(type, 0);
- if (op == NULL) {
- return NULL;
- }
- op->ob_descr = descr;
- op->allocated = size;
- op->weakreflist = NULL;
- Py_SIZE(op) = size;
- if (size <= 0) {
- op->ob_item = NULL;
- }
- else {
- op->ob_item = PyMem_NEW(char, nbytes);
- if (op->ob_item == NULL) {
- Py_DECREF(op);
- return PyErr_NoMemory();
- }
- }
- return (PyObject *) op;
+ nbytes = size * descr->itemsize;
+ /* Check for overflow */
+ if (nbytes / descr->itemsize != (size_t)size) {
+ return PyErr_NoMemory();
+ }
+ op = (arrayobject *) type->tp_alloc(type, 0);
+ if (op == NULL) {
+ return NULL;
+ }
+ op->ob_descr = descr;
+ op->allocated = size;
+ op->weakreflist = NULL;
+ Py_SIZE(op) = size;
+ if (size <= 0) {
+ op->ob_item = NULL;
+ }
+ else {
+ op->ob_item = PyMem_NEW(char, nbytes);
+ if (op->ob_item == NULL) {
+ Py_DECREF(op);
+ return PyErr_NoMemory();
+ }
+ }
+ return (PyObject *) op;
}
static PyObject *
getarrayitem(PyObject *op, Py_ssize_t i)
{
- register arrayobject *ap;
- assert(array_Check(op));
- ap = (arrayobject *)op;
- assert(i>=0 && i<Py_SIZE(ap));
- return (*ap->ob_descr->getitem)(ap, i);
+ register arrayobject *ap;
+ assert(array_Check(op));
+ ap = (arrayobject *)op;
+ assert(i>=0 && i<Py_SIZE(ap));
+ return (*ap->ob_descr->getitem)(ap, i);
}
static int
ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
{
- char *items;
- Py_ssize_t n = Py_SIZE(self);
- if (v == NULL) {
- PyErr_BadInternalCall();
- return -1;
- }
- if ((*self->ob_descr->setitem)(self, -1, v) < 0)
- return -1;
+ char *items;
+ Py_ssize_t n = Py_SIZE(self);
+ if (v == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if ((*self->ob_descr->setitem)(self, -1, v) < 0)
+ return -1;
- if (array_resize(self, n+1) == -1)
- return -1;
- items = self->ob_item;
- if (where < 0) {
- where += n;
- if (where < 0)
- where = 0;
- }
- if (where > n)
- where = n;
- /* appends don't need to call memmove() */
- if (where != n)
- memmove(items + (where+1)*self->ob_descr->itemsize,
- items + where*self->ob_descr->itemsize,
- (n-where)*self->ob_descr->itemsize);
- return (*self->ob_descr->setitem)(self, where, v);
+ if (array_resize(self, n+1) == -1)
+ return -1;
+ items = self->ob_item;
+ if (where < 0) {
+ where += n;
+ if (where < 0)
+ where = 0;
+ }
+ if (where > n)
+ where = n;
+ /* appends don't need to call memmove() */
+ if (where != n)
+ memmove(items + (where+1)*self->ob_descr->itemsize,
+ items + where*self->ob_descr->itemsize,
+ (n-where)*self->ob_descr->itemsize);
+ return (*self->ob_descr->setitem)(self, where, v);
}
/* Methods */
@@ -497,141 +494,141 @@
static void
array_dealloc(arrayobject *op)
{
- if (op->weakreflist != NULL)
- PyObject_ClearWeakRefs((PyObject *) op);
- if (op->ob_item != NULL)
- PyMem_DEL(op->ob_item);
- Py_TYPE(op)->tp_free((PyObject *)op);
+ if (op->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) op);
+ if (op->ob_item != NULL)
+ PyMem_DEL(op->ob_item);
+ Py_TYPE(op)->tp_free((PyObject *)op);
}
static PyObject *
array_richcompare(PyObject *v, PyObject *w, int op)
{
- arrayobject *va, *wa;
- PyObject *vi = NULL;
- PyObject *wi = NULL;
- Py_ssize_t i, k;
- PyObject *res;
+ arrayobject *va, *wa;
+ PyObject *vi = NULL;
+ PyObject *wi = NULL;
+ Py_ssize_t i, k;
+ PyObject *res;
- if (!array_Check(v) || !array_Check(w)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
+ if (!array_Check(v) || !array_Check(w)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
- va = (arrayobject *)v;
- wa = (arrayobject *)w;
+ va = (arrayobject *)v;
+ wa = (arrayobject *)w;
- if (Py_SIZE(va) != Py_SIZE(wa) && (op == Py_EQ || op == Py_NE)) {
- /* Shortcut: if the lengths differ, the arrays differ */
- if (op == Py_EQ)
- res = Py_False;
- else
- res = Py_True;
- Py_INCREF(res);
- return res;
- }
+ if (Py_SIZE(va) != Py_SIZE(wa) && (op == Py_EQ || op == Py_NE)) {
+ /* Shortcut: if the lengths differ, the arrays differ */
+ if (op == Py_EQ)
+ res = Py_False;
+ else
+ res = Py_True;
+ Py_INCREF(res);
+ return res;
+ }
- /* Search for the first index where items are different */
- k = 1;
- for (i = 0; i < Py_SIZE(va) && i < Py_SIZE(wa); i++) {
- vi = getarrayitem(v, i);
- wi = getarrayitem(w, i);
- if (vi == NULL || wi == NULL) {
- Py_XDECREF(vi);
- Py_XDECREF(wi);
- return NULL;
- }
- k = PyObject_RichCompareBool(vi, wi, Py_EQ);
- if (k == 0)
- break; /* Keeping vi and wi alive! */
- Py_DECREF(vi);
- Py_DECREF(wi);
- if (k < 0)
- return NULL;
- }
+ /* Search for the first index where items are different */
+ k = 1;
+ for (i = 0; i < Py_SIZE(va) && i < Py_SIZE(wa); i++) {
+ vi = getarrayitem(v, i);
+ wi = getarrayitem(w, i);
+ if (vi == NULL || wi == NULL) {
+ Py_XDECREF(vi);
+ Py_XDECREF(wi);
+ return NULL;
+ }
+ k = PyObject_RichCompareBool(vi, wi, Py_EQ);
+ if (k == 0)
+ break; /* Keeping vi and wi alive! */
+ Py_DECREF(vi);
+ Py_DECREF(wi);
+ if (k < 0)
+ return NULL;
+ }
- if (k) {
- /* No more items to compare -- compare sizes */
- Py_ssize_t vs = Py_SIZE(va);
- Py_ssize_t ws = Py_SIZE(wa);
- int cmp;
- switch (op) {
- case Py_LT: cmp = vs < ws; break;
- case Py_LE: cmp = vs <= ws; break;
- case Py_EQ: cmp = vs == ws; break;
- case Py_NE: cmp = vs != ws; break;
- case Py_GT: cmp = vs > ws; break;
- case Py_GE: cmp = vs >= ws; break;
- default: return NULL; /* cannot happen */
- }
- if (cmp)
- res = Py_True;
- else
- res = Py_False;
- Py_INCREF(res);
- return res;
- }
+ if (k) {
+ /* No more items to compare -- compare sizes */
+ Py_ssize_t vs = Py_SIZE(va);
+ Py_ssize_t ws = Py_SIZE(wa);
+ int cmp;
+ switch (op) {
+ case Py_LT: cmp = vs < ws; break;
+ case Py_LE: cmp = vs <= ws; break;
+ case Py_EQ: cmp = vs == ws; break;
+ case Py_NE: cmp = vs != ws; break;
+ case Py_GT: cmp = vs > ws; break;
+ case Py_GE: cmp = vs >= ws; break;
+ default: return NULL; /* cannot happen */
+ }
+ if (cmp)
+ res = Py_True;
+ else
+ res = Py_False;
+ Py_INCREF(res);
+ return res;
+ }
- /* We have an item that differs. First, shortcuts for EQ/NE */
- if (op == Py_EQ) {
- Py_INCREF(Py_False);
- res = Py_False;
- }
- else if (op == Py_NE) {
- Py_INCREF(Py_True);
- res = Py_True;
- }
- else {
- /* Compare the final item again using the proper operator */
- res = PyObject_RichCompare(vi, wi, op);
- }
- Py_DECREF(vi);
- Py_DECREF(wi);
- return res;
+ /* We have an item that differs. First, shortcuts for EQ/NE */
+ if (op == Py_EQ) {
+ Py_INCREF(Py_False);
+ res = Py_False;
+ }
+ else if (op == Py_NE) {
+ Py_INCREF(Py_True);
+ res = Py_True;
+ }
+ else {
+ /* Compare the final item again using the proper operator */
+ res = PyObject_RichCompare(vi, wi, op);
+ }
+ Py_DECREF(vi);
+ Py_DECREF(wi);
+ return res;
}
static Py_ssize_t
array_length(arrayobject *a)
{
- return Py_SIZE(a);
+ return Py_SIZE(a);
}
static PyObject *
array_item(arrayobject *a, Py_ssize_t i)
{
- if (i < 0 || i >= Py_SIZE(a)) {
- PyErr_SetString(PyExc_IndexError, "array index out of range");
- return NULL;
- }
- return getarrayitem((PyObject *)a, i);
+ if (i < 0 || i >= Py_SIZE(a)) {
+ PyErr_SetString(PyExc_IndexError, "array index out of range");
+ return NULL;
+ }
+ return getarrayitem((PyObject *)a, i);
}
static PyObject *
array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
{
- arrayobject *np;
- if (ilow < 0)
- ilow = 0;
- else if (ilow > Py_SIZE(a))
- ilow = Py_SIZE(a);
- if (ihigh < 0)
- ihigh = 0;
- if (ihigh < ilow)
- ihigh = ilow;
- else if (ihigh > Py_SIZE(a))
- ihigh = Py_SIZE(a);
- np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr);
- if (np == NULL)
- return NULL;
- memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
- (ihigh-ilow) * a->ob_descr->itemsize);
- return (PyObject *)np;
+ arrayobject *np;
+ if (ilow < 0)
+ ilow = 0;
+ else if (ilow > Py_SIZE(a))
+ ilow = Py_SIZE(a);
+ if (ihigh < 0)
+ ihigh = 0;
+ if (ihigh < ilow)
+ ihigh = ilow;
+ else if (ihigh > Py_SIZE(a))
+ ihigh = Py_SIZE(a);
+ np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr);
+ if (np == NULL)
+ return NULL;
+ memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
+ (ihigh-ilow) * a->ob_descr->itemsize);
+ return (PyObject *)np;
}
static PyObject *
array_copy(arrayobject *a, PyObject *unused)
{
- return array_slice(a, 0, Py_SIZE(a));
+ return array_slice(a, 0, Py_SIZE(a));
}
PyDoc_STRVAR(copy_doc,
@@ -642,297 +639,297 @@
static PyObject *
array_concat(arrayobject *a, PyObject *bb)
{
- Py_ssize_t size;
- arrayobject *np;
- if (!array_Check(bb)) {
- PyErr_Format(PyExc_TypeError,
- "can only append array (not \"%.200s\") to array",
- Py_TYPE(bb)->tp_name);
- return NULL;
- }
+ Py_ssize_t size;
+ arrayobject *np;
+ if (!array_Check(bb)) {
+ PyErr_Format(PyExc_TypeError,
+ "can only append array (not \"%.200s\") to array",
+ Py_TYPE(bb)->tp_name);
+ return NULL;
+ }
#define b ((arrayobject *)bb)
- if (a->ob_descr != b->ob_descr) {
- PyErr_BadArgument();
- return NULL;
- }
- if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) {
- return PyErr_NoMemory();
- }
- size = Py_SIZE(a) + Py_SIZE(b);
- np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
- if (np == NULL) {
- return NULL;
- }
- memcpy(np->ob_item, a->ob_item, Py_SIZE(a)*a->ob_descr->itemsize);
- memcpy(np->ob_item + Py_SIZE(a)*a->ob_descr->itemsize,
- b->ob_item, Py_SIZE(b)*b->ob_descr->itemsize);
- return (PyObject *)np;
+ if (a->ob_descr != b->ob_descr) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) {
+ return PyErr_NoMemory();
+ }
+ size = Py_SIZE(a) + Py_SIZE(b);
+ np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
+ if (np == NULL) {
+ return NULL;
+ }
+ memcpy(np->ob_item, a->ob_item, Py_SIZE(a)*a->ob_descr->itemsize);
+ memcpy(np->ob_item + Py_SIZE(a)*a->ob_descr->itemsize,
+ b->ob_item, Py_SIZE(b)*b->ob_descr->itemsize);
+ return (PyObject *)np;
#undef b
}
static PyObject *
array_repeat(arrayobject *a, Py_ssize_t n)
{
- Py_ssize_t i;
- Py_ssize_t size;
- arrayobject *np;
- char *p;
- Py_ssize_t nbytes;
- if (n < 0)
- n = 0;
- if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) {
- return PyErr_NoMemory();
- }
- size = Py_SIZE(a) * n;
- np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
- if (np == NULL)
- return NULL;
- p = np->ob_item;
- nbytes = Py_SIZE(a) * a->ob_descr->itemsize;
- for (i = 0; i < n; i++) {
- memcpy(p, a->ob_item, nbytes);
- p += nbytes;
- }
- return (PyObject *) np;
+ Py_ssize_t i;
+ Py_ssize_t size;
+ arrayobject *np;
+ char *p;
+ Py_ssize_t nbytes;
+ if (n < 0)
+ n = 0;
+ if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) {
+ return PyErr_NoMemory();
+ }
+ size = Py_SIZE(a) * n;
+ np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
+ if (np == NULL)
+ return NULL;
+ p = np->ob_item;
+ nbytes = Py_SIZE(a) * a->ob_descr->itemsize;
+ for (i = 0; i < n; i++) {
+ memcpy(p, a->ob_item, nbytes);
+ p += nbytes;
+ }
+ return (PyObject *) np;
}
static int
array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
{
- char *item;
- Py_ssize_t n; /* Size of replacement array */
- Py_ssize_t d; /* Change in size */
+ char *item;
+ Py_ssize_t n; /* Size of replacement array */
+ Py_ssize_t d; /* Change in size */
#define b ((arrayobject *)v)
- if (v == NULL)
- n = 0;
- else if (array_Check(v)) {
- n = Py_SIZE(b);
- if (a == b) {
- /* Special case "a[i:j] = a" -- copy b first */
- int ret;
- v = array_slice(b, 0, n);
- if (!v)
- return -1;
- ret = array_ass_slice(a, ilow, ihigh, v);
- Py_DECREF(v);
- return ret;
- }
- if (b->ob_descr != a->ob_descr) {
- PyErr_BadArgument();
- return -1;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "can only assign array (not \"%.200s\") to array slice",
- Py_TYPE(v)->tp_name);
- return -1;
- }
- if (ilow < 0)
- ilow = 0;
- else if (ilow > Py_SIZE(a))
- ilow = Py_SIZE(a);
- if (ihigh < 0)
- ihigh = 0;
- if (ihigh < ilow)
- ihigh = ilow;
- else if (ihigh > Py_SIZE(a))
- ihigh = Py_SIZE(a);
- item = a->ob_item;
- d = n - (ihigh-ilow);
- if (d < 0) { /* Delete -d items */
- memmove(item + (ihigh+d)*a->ob_descr->itemsize,
- item + ihigh*a->ob_descr->itemsize,
- (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize);
- Py_SIZE(a) += d;
- PyMem_RESIZE(item, char, Py_SIZE(a)*a->ob_descr->itemsize);
- /* Can't fail */
- a->ob_item = item;
- a->allocated = Py_SIZE(a);
- }
- else if (d > 0) { /* Insert d items */
- PyMem_RESIZE(item, char,
- (Py_SIZE(a) + d)*a->ob_descr->itemsize);
- if (item == NULL) {
- PyErr_NoMemory();
- return -1;
- }
- memmove(item + (ihigh+d)*a->ob_descr->itemsize,
- item + ihigh*a->ob_descr->itemsize,
- (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize);
- a->ob_item = item;
- Py_SIZE(a) += d;
- a->allocated = Py_SIZE(a);
- }
- if (n > 0)
- memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
- n*b->ob_descr->itemsize);
- return 0;
+ if (v == NULL)
+ n = 0;
+ else if (array_Check(v)) {
+ n = Py_SIZE(b);
+ if (a == b) {
+ /* Special case "a[i:j] = a" -- copy b first */
+ int ret;
+ v = array_slice(b, 0, n);
+ if (!v)
+ return -1;
+ ret = array_ass_slice(a, ilow, ihigh, v);
+ Py_DECREF(v);
+ return ret;
+ }
+ if (b->ob_descr != a->ob_descr) {
+ PyErr_BadArgument();
+ return -1;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "can only assign array (not \"%.200s\") to array slice",
+ Py_TYPE(v)->tp_name);
+ return -1;
+ }
+ if (ilow < 0)
+ ilow = 0;
+ else if (ilow > Py_SIZE(a))
+ ilow = Py_SIZE(a);
+ if (ihigh < 0)
+ ihigh = 0;
+ if (ihigh < ilow)
+ ihigh = ilow;
+ else if (ihigh > Py_SIZE(a))
+ ihigh = Py_SIZE(a);
+ item = a->ob_item;
+ d = n - (ihigh-ilow);
+ if (d < 0) { /* Delete -d items */
+ memmove(item + (ihigh+d)*a->ob_descr->itemsize,
+ item + ihigh*a->ob_descr->itemsize,
+ (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize);
+ Py_SIZE(a) += d;
+ PyMem_RESIZE(item, char, Py_SIZE(a)*a->ob_descr->itemsize);
+ /* Can't fail */
+ a->ob_item = item;
+ a->allocated = Py_SIZE(a);
+ }
+ else if (d > 0) { /* Insert d items */
+ PyMem_RESIZE(item, char,
+ (Py_SIZE(a) + d)*a->ob_descr->itemsize);
+ if (item == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ memmove(item + (ihigh+d)*a->ob_descr->itemsize,
+ item + ihigh*a->ob_descr->itemsize,
+ (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize);
+ a->ob_item = item;
+ Py_SIZE(a) += d;
+ a->allocated = Py_SIZE(a);
+ }
+ if (n > 0)
+ memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
+ n*b->ob_descr->itemsize);
+ return 0;
#undef b
}
static int
array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v)
{
- if (i < 0 || i >= Py_SIZE(a)) {
- PyErr_SetString(PyExc_IndexError,
- "array assignment index out of range");
- return -1;
- }
- if (v == NULL)
- return array_ass_slice(a, i, i+1, v);
- return (*a->ob_descr->setitem)(a, i, v);
+ if (i < 0 || i >= Py_SIZE(a)) {
+ PyErr_SetString(PyExc_IndexError,
+ "array assignment index out of range");
+ return -1;
+ }
+ if (v == NULL)
+ return array_ass_slice(a, i, i+1, v);
+ return (*a->ob_descr->setitem)(a, i, v);
More information about the pypy-commit
mailing list