add python-opendir, an extension module using POSIX opendir semantics
authorMichael Lauer <mickey@vanille-media.de>
Tue, 8 Jul 2008 09:18:11 +0000 (09:18 +0000)
committerMichael Lauer <mickey@vanille-media.de>
Tue, 8 Jul 2008 09:18:11 +0000 (09:18 +0000)
packages/python/python-opendir/.mtn2git_empty [new file with mode: 0644]
packages/python/python-opendir/opendir.pyx [new file with mode: 0644]
packages/python/python-opendir/setup.py [new file with mode: 0644]
packages/python/python-opendir_1.0.bb [new file with mode: 0644]
packages/tasks/task-python-everything.bb

diff --git a/packages/python/python-opendir/.mtn2git_empty b/packages/python/python-opendir/.mtn2git_empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packages/python/python-opendir/opendir.pyx b/packages/python/python-opendir/opendir.pyx
new file mode 100644 (file)
index 0000000..1ee81f7
--- /dev/null
@@ -0,0 +1,149 @@
+##############################################################
+#
+#   opendir.pyx - A class exposing the functionality of
+#   ===========   the opendir() family of C libary functions.
+#
+#   By Gregory Ewing
+#   greg.ewing@canterbury.ac.nz
+#
+#   This software and derivative works created from it
+#   may be used and redistributed without restriction.
+#
+##############################################################
+
+cdef extern from "sys/errno.h":
+       int errno
+
+cdef extern from "stdio.h":
+       char *strerror(int)
+
+cdef extern from "dirent.h":
+       ctypedef struct DIR
+       struct dirent:
+               int d_namlen
+               char d_name[1]
+       DIR *c_opendir "opendir" (char *)
+       int readdir_r(DIR *, dirent *, dirent **)
+       long telldir(DIR *)
+       void seekdir(DIR *, long)
+       void rewinddir(DIR *)
+       int closedir(DIR *)
+       int dirfd(DIR *)
+
+#------------------------------------------------------------------
+
+cdef class opendir:
+       """opendir(pathname) --> an open directory object
+       
+       Opens a directory and provides incremental access to
+       the filenames it contains. May be used as a file-like
+       object or as an iterator.
+       
+       When used as a file-like object, each call to read()
+       returns one filename, or an empty string when the end
+       of the directory is reached. The close() method should
+       be called when finished with the directory.
+       
+       The close() method should also be called when used as
+       an iterator and iteration is stopped prematurely. If
+       iteration proceeds to completion, the directory is
+       closed automatically."""
+
+       cdef DIR *dir
+       
+       def __cinit__(self, char *path):
+               self.dir = c_opendir(path)
+               if not self.dir:
+                       raise IOError(errno, "%s: '%s'" % (strerror(errno), path))
+       
+       def __dealloc__(self):
+               if self.dir:
+                       closedir(self.dir)
+
+       def read(self):
+               """read() --> filename or empty string
+               
+               Returns the next filename from the directory, or an empty
+               string if the end of the directory has been reached."""
+               
+               cdef dirent entry, *result
+               check_open(self)
+               if readdir_r(self.dir, &entry, &result) < 0:
+                       raise IOError(errno)
+               if result:
+                       return entry.d_name
+               else:
+                       return ""
+       
+       def tell(self):
+               """tell() --> position
+               
+               Returns a value representing the current position in the
+               directory, suitable for passing to tell(). Only valid for
+               this directory object as long as it remains open."""
+               
+               check_open(self)
+               return telldir(self.dir)
+
+       def seek(self, long pos):
+               """seek(position)
+               
+               Returns the directory to the specified position, which
+               should be a value previously returned by tell()."""
+               
+               check_open(self)
+               seekdir(self.dir, pos)
+       
+       def rewind(self):
+               """rewind()
+               
+               Resets the position to the beginning of the directory."""
+               
+               check_open(self)
+               rewinddir(self.dir)
+       
+       def close(self):
+               """close()
+               
+               Closes the directory and frees the underlying file descriptor."""
+               
+               if self.dir:
+                       if closedir(self.dir) < 0:
+                               raise IOError(errno)
+                       self.dir = NULL
+
+#  MaxOSX doesn't seem to have dirfd, despite what the
+#  man page says. :-(
+#
+#      def fileno(self):
+#              """fileno() --> file descriptor
+#              
+#              Returns the file descriptor associated with the open directory."""
+#
+#              check_open(self)
+#              return dirfd(self.dir)
+
+       def __iter__(self):
+               return self
+       
+       def __next__(self):
+               """next() --> filename
+               
+               Returns the next filename from the directory. If the end of the
+               directory has been reached, closes the directory and raises
+               StopIteration."""
+
+               if self.dir:
+                       result = self.read()
+                       if result:
+                               return result
+                       self.close()
+               raise StopIteration
+
+#------------------------------------------------------------------
+
+cdef int check_open(opendir d) except -1:
+       if not d.dir:
+               raise ValueError("Directory is closed")
+       return 0
+
diff --git a/packages/python/python-opendir/setup.py b/packages/python/python-opendir/setup.py
new file mode 100644 (file)
index 0000000..d76b22c
--- /dev/null
@@ -0,0 +1,25 @@
+from distutils.core import setup
+from distutils.extension import Extension
+from Cython.Distutils import build_ext
+
+setup(
+  name = 'opendir',
+  version = '0.0.1',
+  author = 'Gregory Ewing',
+  author_email = 'greg ewing at canterbury ac nz',
+  maintainer = 'Johannes "josch" Schauer',
+  maintainer_email = 'j schauer at email de',
+  description = 'Implements POSIX opendir',
+  classifiers = [
+    'Development Status :: 4 - Beta',
+    'Intended Audience :: Developers',
+    'Operating System :: POSIX',
+    'Programming Language :: Pyrex',
+    'Topic :: Software Development :: Libraries :: Python Modules',
+    'Topic :: System :: Filesystems'
+  ],
+  ext_modules=[ 
+    Extension("opendir", ["opendir.pyx"]),
+    ],
+  cmdclass = {'build_ext': build_ext}
+)
diff --git a/packages/python/python-opendir_1.0.bb b/packages/python/python-opendir_1.0.bb
new file mode 100644 (file)
index 0000000..88f22a1
--- /dev/null
@@ -0,0 +1,15 @@
+DESCRIPTION = "POSIX opendir support for Python"
+SECTION = "devel/python"
+PRIORITY = "optional"
+LICENSE = "PD"
+HOMEPAGE = "http://rabenfrost.net/mokopedia/opendir/"
+DEPENDS = "python-pyrex-native python-cython-native"
+PR = "ml0"
+
+SRC_URI = "\
+  file://opendir.pyx \
+  file://setup.py \
+"
+S = "${WORKDIR}"
+
+inherit distutils
index 669c941..6233374 100644 (file)
@@ -1,7 +1,7 @@
 DESCRIPTION= "Everything Python"
 HOMEPAGE = "http://www.vanille.de/projects/python.spy"
 LICENSE = "MIT"
-PR = "ml30"
+PR = "ml31"
 
 RDEPENDS = "\
                python-ao               \
@@ -36,6 +36,7 @@ RDEPENDS = "\
                python-numarray         \
                python-numeric          \
                python-ogg              \
+               python-opendir          \
                python-pexpect          \
                python-pyalsa           \
                python-pyalsaaudio      \