[pypy-svn] r18791 - in pypy/dist/pypy/rpython: . module module/test
arigo at codespeak.net
arigo at codespeak.net
Thu Oct 20 13:18:27 CEST 2005
Author: arigo
Date: Thu Oct 20 13:18:26 2005
New Revision: 18791
Modified:
pypy/dist/pypy/rpython/annlowlevel.py
pypy/dist/pypy/rpython/extfunctable.py
pypy/dist/pypy/rpython/module/ll_os.py
pypy/dist/pypy/rpython/module/support.py
pypy/dist/pypy/rpython/module/test/test_ll_os.py
pypy/dist/pypy/rpython/ros.py
pypy/dist/pypy/rpython/rspecialcase.py
Log:
* RPythonic helpers to implement os.listdir(): the C-ish functions
ros.opendir(), readdir(), closedir().
* support for external types that are externally-managed pointers
(used here for the DIR* pointer). This means that closedir()
must be called explicitely from RPython!
Modified: pypy/dist/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/dist/pypy/rpython/annlowlevel.py (original)
+++ pypy/dist/pypy/rpython/annlowlevel.py Thu Oct 20 13:18:26 2005
@@ -80,6 +80,11 @@
exttypeinfo = s_opaqueptr.ll_ptrtype.TO._exttypeinfo
return annmodel.SomeExternalObject(exttypeinfo.typ)
+ def override__to_opaque_object(pol, s_value):
+ assert isinstance(s_value, annmodel.SomeExternalObject)
+ exttypeinfo = extfunctable.typetable[s_value.knowntype]
+ return annmodel.SomePtr(lltype.Ptr(exttypeinfo.get_lltype()))
+
def annotate_lowlevel_helper(annotator, ll_function, args_s):
saved = annotator.policy, annotator.added_blocks
Modified: pypy/dist/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py (original)
+++ pypy/dist/pypy/rpython/extfunctable.py Thu Oct 20 13:18:26 2005
@@ -28,11 +28,12 @@
class ExtTypeInfo:
- def __init__(self, typ, tag, methods):
+ def __init__(self, typ, tag, methods, needs_container=True):
self.typ = typ
self.tag = tag
self._TYPE = None
self.methods = methods # {'name': ExtFuncInfo()}
+ self.needs_container = needs_container
def get_annotation(self, methodname):
return self.methods[methodname].annotation
@@ -51,8 +52,11 @@
from pypy.rpython import lltype
OPAQUE = lltype.OpaqueType(self.tag)
OPAQUE._exttypeinfo = self
- STRUCT = lltype.GcStruct(self.tag, ('obj', OPAQUE))
- self._TYPE = STRUCT
+ if self.needs_container:
+ STRUCT = lltype.GcStruct(self.tag, ('obj', OPAQUE))
+ self._TYPE = STRUCT
+ else:
+ self._TYPE = OPAQUE
return self._TYPE
@@ -87,7 +91,7 @@
return info
typetable = {}
-def declaretype(typ, tag, **methodsdecl):
+def declaretype1(typ, tag, methodsdecl, needs_container):
assert isinstance(typ, type)
methods = {}
for name, args in methodsdecl.items():
@@ -99,12 +103,18 @@
else:
func = None # failed (typical for old-style C types), ignore it
methods[name] = declare(func, *args)
- info = ExtTypeInfo(typ, tag, methods)
+ info = ExtTypeInfo(typ, tag, methods, needs_container)
typetable[typ] = info
for callback in table_callbacks:
callback()
return info
+def declaretype(typ, tag, **methodsdecl):
+ return declaretype1(typ, tag, methodsdecl, needs_container=True)
+
+def declareptrtype(typ, tag, **methodsdecl):
+ return declaretype1(typ, tag, methodsdecl, needs_container=False)
+
# _____________________________________________________________
@@ -204,6 +214,10 @@
from pypy.rpython import ros
declare(ros.putenv, noneannotation, 'll_os/putenv')
declare(ros.environ, strnullannotation, 'll_os/environ')
+declare(ros.opendir, ros.DIR, 'll_os/opendir')
+declareptrtype(ros.DIR, "DIR",
+ readdir = (strnullannotation, 'll_os/readdir'),
+ closedir = (noneannotation, 'll_os/closedir'))
# ___________________________________________________________
# stackless
Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/ll_os.py Thu Oct 20 13:18:26 2005
@@ -17,6 +17,7 @@
from pypy.rpython.rstr import STR
from pypy.rpython.lltype import GcStruct, Signed, Array, Char, Ptr, malloc
from pypy.rpython.module.support import to_rstr, from_rstr, ll_strcpy
+from pypy.rpython.module.support import to_opaque_object, from_opaque_object
from pypy.rpython import ros
def ll_os_open(fname, flag, mode):
@@ -147,3 +148,22 @@
def ll_os_environ(idx):
return ros.environ(idx)
ll_os_environ.suggested_primitive = True
+
+# ____________________________________________________________
+# opendir/readdir
+
+def ll_os_opendir(dirname):
+ dir = ros.opendir(from_rstr(dirname))
+ return to_opaque_object(dir)
+ll_os_opendir.suggested_primitive = True
+
+def ll_os_readdir(opaquedir):
+ dir = from_opaque_object(opaquedir)
+ nextentry = dir.readdir()
+ return to_rstr(nextentry)
+ll_os_readdir.suggested_primitive = True
+
+def ll_os_closedir(opaquedir):
+ dir = from_opaque_object(opaquedir)
+ dir.closedir()
+ll_os_closedir.suggested_primitive = True
Modified: pypy/dist/pypy/rpython/module/support.py
==============================================================================
--- pypy/dist/pypy/rpython/module/support.py (original)
+++ pypy/dist/pypy/rpython/module/support.py Thu Oct 20 13:18:26 2005
@@ -6,13 +6,18 @@
# utility conversion functions
def to_rstr(s):
+ if s is None:
+ return lltype.nullptr(STR)
p = malloc(STR, len(s))
for i in range(len(s)):
p.chars[i] = s[i]
return p
def from_rstr(rs):
- return ''.join([rs.chars[i] for i in range(len(rs.chars))])
+ if not rs: # null pointer
+ return None
+ else:
+ return ''.join([rs.chars[i] for i in range(len(rs.chars))])
def ll_strcpy(dstchars, srcchars, n):
i = 0
@@ -29,3 +34,10 @@
"NOT_RPYTHON"
return opaqueptr._obj.externalobj
from_opaque_object._annspecialcase_ = "override:from_opaque_object"
+
+def to_opaque_object(value):
+ "NOT_RPYTHON"
+ exttypeinfo = extfunctable.typetable[value.__class__]
+ return lltype.opaqueptr(exttypeinfo.get_lltype(), 'opaque',
+ externalobj=value)
+to_opaque_object._annspecialcase_ = "override:to_opaque_object"
Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/test/test_ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/test/test_ll_os.py Thu Oct 20 13:18:26 2005
@@ -80,3 +80,24 @@
assert res
chan.close()
+def test_opendir_readdir():
+ dirname = str(udir)
+ rsdirname = to_rstr(dirname)
+ result = []
+ DIR = ll_os_opendir(rsdirname)
+ try:
+ while True:
+ nextentry = ll_os_readdir(DIR)
+ if not nextentry: # null pointer check
+ break
+ result.append(from_rstr(nextentry))
+ finally:
+ ll_os_closedir(DIR)
+ assert '.' in result
+ assert '..' in result
+ result.remove('.')
+ result.remove('..')
+ result.sort()
+ compared_with = os.listdir(dirname)
+ compared_with.sort()
+ assert result == compared_with
Modified: pypy/dist/pypy/rpython/ros.py
==============================================================================
--- pypy/dist/pypy/rpython/ros.py (original)
+++ pypy/dist/pypy/rpython/ros.py Thu Oct 20 13:18:26 2005
@@ -15,3 +15,23 @@
# we simulate the environ list
if idx < len(_initial_items):
return '%s=%s' % _initial_items[idx]
+
+
+class DIR(object):
+ # a simulated DIR structure from C, i.e. a directory opened by
+ # opendir() from which we can enumerate the entries with readdir().
+ # Like readdir(), this version does not hide the '.' and '..' entries.
+ def __init__(self, dirname):
+ self._entries = iter(['.', '..'] + os.listdir(dirname))
+
+ def readdir(self):
+ try:
+ return self._entries.next()
+ except StopIteration:
+ return None
+
+ def closedir(self):
+ pass
+
+def opendir(dirname):
+ return DIR(dirname)
Modified: pypy/dist/pypy/rpython/rspecialcase.py
==============================================================================
--- pypy/dist/pypy/rpython/rspecialcase.py (original)
+++ pypy/dist/pypy/rpython/rspecialcase.py Thu Oct 20 13:18:26 2005
@@ -40,3 +40,7 @@
def rtype_override_from_opaque_object(hop, clsdef):
return hop.genop('from_opaque_object_should_never_be_seen_by_the_backend',
[], resulttype=hop.r_result)
+
+def rtype_override_to_opaque_object(hop, clsdef):
+ return hop.genop('to_opaque_object_should_never_be_seen_by_the_backend',
+ [], resulttype=hop.r_result)
More information about the Pypy-commit
mailing list