]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Misc changes and new modules. whrandom is "objectified". SOCKET.py
authorGuido van Rossum <guido@python.org>
Sun, 18 Oct 1992 17:09:59 +0000 (17:09 +0000)
committerGuido van Rossum <guido@python.org>
Sun, 18 Oct 1992 17:09:59 +0000 (17:09 +0000)
is moved to the sgi subdirectory.

Lib/calendar.py
Lib/imghdr.py
Lib/irix5/torgb.py [new file with mode: 0755]
Lib/pipes.py [new file with mode: 0644]
Lib/plat-irix5/torgb.py [new file with mode: 0755]
Lib/string.py
Lib/stringold.py
Lib/toaiff.py [new file with mode: 0644]
Lib/tzparse.py [new file with mode: 0644]
Lib/whrandom.py

index 4e02e0ed8f7f33e3d50e7bb120dd332a177295b2..62fb27fb1d248a3da36436fc5657130eccc63959 100644 (file)
@@ -11,7 +11,7 @@
 # - Monday is the first day of the week (numbered 0)
 
 # These are really parameters of the 'time' module:
-epoch = 1970           # Time began on January 1 of this year (00:00:00 UCT)
+epoch = 1970           # Time began on January 1 of this year (00:00:00 UTC)
 day_0 = 3              # The epoch begins on a Thursday (Monday = 0)
 
 # Return 1 for leap years, 0 for non-leap years
@@ -58,7 +58,7 @@ def leapdays(y1, y2):
        return (y2+3)/4 - (y1+3)/4
 
 # Inverse of gmtime():
-# Turn UCT calendar time (less yday, wday) into seconds since epoch
+# Turn UTC calendar time (less yday, wday) into seconds since epoch
 def mktime(year, month, day, hours, mins, secs):
        days = day - 1
        for m in range(January, month): days = days + mdays[m]
@@ -96,8 +96,8 @@ def asctime(year, month, day, hours, mins, secs, yday, wday):
        return s + ' ' + `year`
 
 # Localization: Minutes West from Greenwich
-# timezone = -2*60     # Middle-European time with DST on
-timezone = 5*60                # EST (sigh -- THINK time() doesn't return UCT)
+timezone = -2*60       # Middle-European time with DST on
+# timezone = 5*60      # EST (sigh -- THINK time() doesn't return UTC)
 
 # Local time ignores DST issues for now -- adjust 'timezone' to fake it
 def localtime(secs):
index 981340fff075f80f847934d4542772b1f3efb723..063bfe82ce55753bc20bee0140dba8a819981641 100644 (file)
@@ -35,13 +35,29 @@ def test_gif(h, f):
 
 tests.append(test_gif)
 
-def test_pnm(h, f):
-       # PBM, PGM, PPM (portable {bit,gray,pix}map; together portable anymap)
+def test_pbm(h, f):
+       # PBM (portable bitmap)
        if len(h) >= 3 and \
-               h[0] == 'P' and h[1] in '123456' and h[2] in ' \t\n\r':
-               return 'pnm'
+               h[0] == 'P' and h[1] in '14' and h[2] in ' \t\n\r':
+               return 'pbm'
 
-tests.append(test_pnm)
+tests.append(test_pbm)
+
+def test_pgm(h, f):
+       # PGM (portable graymap)
+       if len(h) >= 3 and \
+               h[0] == 'P' and h[1] in '25' and h[2] in ' \t\n\r':
+               return 'pgm'
+
+tests.append(test_pgm)
+
+def test_ppm(h, f):
+       # PPM (portable pixmap)
+       if len(h) >= 3 and \
+               h[0] == 'P' and h[1] in '36' and h[2] in ' \t\n\r':
+               return 'ppm'
+
+tests.append(test_ppm)
 
 def test_tiff(h, f):
        # TIFF (can be in Motorola or Intel byte order)
diff --git a/Lib/irix5/torgb.py b/Lib/irix5/torgb.py
new file mode 100755 (executable)
index 0000000..e46aca3
--- /dev/null
@@ -0,0 +1,91 @@
+# Convert "arbitrary" image files to rgb files (SGI's image format).
+# Input may be compressed.
+# The uncompressed file type may be PBM, PGM, PPM, GIF, TIFF, or Sun raster.
+# An exception is raised if the file is not of a recognized type.
+# Returned filename is either the input filename or a temporary filename;
+# in the latter case the caller must ensure that it is removed.
+# Other temporary files used are removed by the function.
+
+import os
+import tempfile
+import pipes
+import imghdr
+
+table = {}
+
+t = pipes.Template().init()
+t.append('fromppm $IN $OUT', 'ff')
+table['ppm'] = t
+
+t = pipes.Template().init()
+t.append('pnmtoppm', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['pnm'] = t
+table['pgm'] = t
+table['pbm'] = t
+
+t = pipes.Template().init()
+t.append('fromgif $IN $OUT', 'ff')
+table['gif'] = t
+
+t = pipes.Template().init()
+t.append('tifftopnm', '--')
+t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['tiff'] = t
+
+t = pipes.Template().init()
+t.append('rasttopnm', '--')
+t.append('pnmtoppm', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['rast'] = t
+
+uncompress = pipes.Template().init()
+uncompress.append('uncompress', '--')
+
+
+error = 'torgb.error' # Exception
+
+def torgb(filename):
+       temps = []
+       ret = None
+       try:
+               ret = _torgb(filename, temps)
+       finally:
+               for temp in temps[:]:
+                       if temp <> ret:
+                               try:
+                                       os.unlink(temp)
+                               except os.error:
+                                       pass
+                               temps.remove(temp)
+       return ret
+
+def _torgb(filename, temps):
+       if filename[-2:] == '.Z':
+               fname = tempfile.mktemp()
+               temps.append(fname)
+               sts = uncompress.copy(filename, fname)
+               if sts:
+                       raise error, filename + ': uncompress failed'
+       else:
+               fname = filename
+       try:
+               ftype = imghdr.what(fname)
+       except IOError, msg:
+               if type(msg) == type(()) and len(msg) == 2 and \
+                       type(msg[0]) == type(0) and type(msg[1]) == type(''):
+                       msg = msg[1]
+               if type(msg) <> type(''):
+                       msg = `msg`
+               raise error, filename + ': ' + msg
+       if ftype == 'rgb':
+               return fname
+       if ftype == None or not table.has_key(ftype):
+               raise error, \
+                       filename + ': unsupported image file type ' + `ftype`
+       temp = tempfile.mktemp()
+       sts = table[ftype].copy(fname, temp)
+       if sts:
+               raise error, filename + ': conversion to rgb failed'
+       return temp
diff --git a/Lib/pipes.py b/Lib/pipes.py
new file mode 100644 (file)
index 0000000..426c377
--- /dev/null
@@ -0,0 +1,302 @@
+# Conversion pipeline templates
+# =============================
+
+
+# The problem:
+# ------------
+# 
+# Suppose you have some data that you want to convert to another format
+# (e.g. from GIF image format to PPM image format).  Maybe the
+# conversion involves several steps (e.g. piping it through compress or
+# uuencode).  Some of the conversion steps may require that their input
+# is a disk file, others may be able to read standard input; similar for
+# their output.  The input to the entire conversion may also be read
+# from a disk file or from an open file, and similar for its output.
+# 
+# The module lets you construct a pipeline template by sticking one or
+# more conversion steps together.  It will take care of creating and
+# removing temporary files if they are necessary to hold intermediate
+# data.  You can then use the template to do conversions from many
+# different sources to many different destinations.  The temporary
+# file names used are different each time the template is used.
+#
+# The templates are objects so you can create templates for many
+# different conversion steps and store them in a dictionary, for
+# instance.
+
+
+# Directions:
+# -----------
+#
+# To create a template:
+#   t = Template().init()
+#
+# To add a conversion step to a template:
+#   t.append(command, kind)
+# where kind is a string of two characters: the first is '-' if the
+# command reads its standard input or 'f' if it requires a file; the
+# second likewise for the output. The command must be valid /bin/sh
+# syntax.  If input or output files are required, they are passed as
+# $IN and $OUT; otherwise, it must be  possible to use the command in
+# a pipeline.
+#
+# To add a conversion step at the beginning:
+#   t.prepend(command, kind)
+#
+# To convert a file to another file using a template:
+#   sts = t.copy(infile, outfile)
+# If infile or outfile are the empty string, standard input is read or
+# standard output is written, respectively.  The return value is the
+# exit status of the conversion pipeline.
+# 
+# To open a file for reading or writing through a conversion pipeline:
+#   fp = t.open(file, mode)
+# where mode is 'r' to read the file, or 'w' to write it -- just like
+# for the built-in function open() or for os.popen().
+#
+# To create a new template object initialized to a given one:
+#   t2 = t.clone()
+#
+# For an example, see the function test() at the end of the file.
+
+
+import sys
+import regex
+
+import os
+import tempfile
+import string
+
+
+# Conversion step kinds
+
+FILEIN_FILEOUT = 'ff'                  # Must read & write real files
+STDIN_FILEOUT  = '-f'                  # Must write a real file
+FILEIN_STDOUT  = 'f-'                  # Must read a real file
+STDIN_STDOUT   = '--'                  # Normal pipeline element
+SOURCE         = '.-'                  # Must be first, writes stdout
+SINK           = '-.'                  # Must be last, reads stdin
+
+stepkinds = [FILEIN_FILEOUT, STDIN_FILEOUT, FILEIN_STDOUT, STDIN_STDOUT, \
+            SOURCE, SINK]
+
+
+# A pipeline template is a Template object:
+
+class Template:
+
+       # Template().init() returns a fresh pipeline template
+       def init(self):
+               self.debugging = 0
+               self.reset()
+               return self
+
+       # t.__repr__() implements `t`
+       def __repr__(self):
+               return '<Template instance, steps=' + `self.steps` + '>'
+
+       # t.reset() restores a pipeline template to its initial state
+       def reset(self):
+               self.steps = []
+
+       # t.clone() returns a new pipeline template with identical
+       # initial state as the current one
+       def clone(self):
+               t = Template().init()
+               t.steps = self.steps[:]
+               t.debugging = self.debugging
+               return t
+
+       # t.debug(flag) turns debugging on or off
+       def debug(self, flag):
+               self.debugging = flag
+
+       # t.append(cmd, kind) adds a new step at the end
+       def append(self, cmd, kind):
+               if type(cmd) <> type(''):
+                       raise TypeError, \
+                             'Template.append: cmd must be a string'
+               if kind not in stepkinds:
+                       raise ValueError, \
+                             'Template.append: bad kind ' + `kind`
+               if kind == SOURCE:
+                       raise ValueError, \
+                             'Template.append: SOURCE can only be prepended'
+               if self.steps <> [] and self.steps[-1][1] == SINK:
+                       raise ValueError, \
+                             'Template.append: already ends with SINK'
+               if kind[0] == 'f' and regex.search('\$IN', cmd) < 0:
+                       raise ValueError, \
+                             'Template.append: missing $IN in cmd'
+               if kind[1] == 'f' and regex.search('\$OUT', cmd) < 0:
+                       raise ValueError, \
+                             'Template.append: missing $OUT in cmd'
+               self.steps.append((cmd, kind))
+
+       # t.prepend(cmd, kind) adds a new step at the front
+       def prepend(self, cmd, kind):
+               if type(cmd) <> type(''):
+                       raise TypeError, \
+                             'Template.prepend: cmd must be a string'
+               if kind not in stepkinds:
+                       raise ValueError, \
+                             'Template.prepend: bad kind ' + `kind`
+               if kind == SINK:
+                       raise ValueError, \
+                             'Template.prepend: SINK can only be appended'
+               if self.steps <> [] and self.steps[0][1] == SOURCE:
+                       raise ValueError, \
+                             'Template.prepend: already begins with SOURCE'
+               if kind[0] == 'f' and regex.search('\$IN\>', cmd) < 0:
+                       raise ValueError, \
+                             'Template.prepend: missing $IN in cmd'
+               if kind[1] == 'f' and regex.search('\$OUT\>', cmd) < 0:
+                       raise ValueError, \
+                             'Template.prepend: missing $OUT in cmd'
+               self.steps.insert(0, (cmd, kind))
+
+       # t.open(file, rw) returns a pipe or file object open for
+       # reading or writing; the file is the other end of the pipeline
+       def open(self, file, rw):
+               if rw == 'r':
+                       return self.open_r(file)
+               if rw == 'w':
+                       return self.open_w(file)
+               raise ValueError, \
+                     'Template.open: rw must be \'r\' or \'w\', not ' + `rw`
+
+       # t.open_r(file) and t.open_w(file) implement
+       # t.open(file, 'r') and t.open(file, 'w') respectively
+
+       def open_r(self, file):
+               if self.steps == []:
+                       return open(file, 'r')
+               if self.steps[-1][1] == SINK:
+                       raise ValueError, \
+                             'Template.open_r: pipeline ends width SINK'
+               cmd = self.makepipeline(file, '')
+               return os.popen(cmd, 'r')
+
+       def open_w(self, file):
+               if self.steps == []:
+                       return open(file, 'w')
+               if self.steps[0][1] == SOURCE:
+                       raise ValueError, \
+                             'Template.open_w: pipeline begins with SOURCE'
+               cmd = self.makepipeline('', file)
+               return os.popen(cmd, 'w')
+
+       def copy(self, infile, outfile):
+               return os.system(self.makepipeline(infile, outfile))
+
+       def makepipeline(self, infile, outfile):
+               cmd = makepipeline(infile, self.steps, outfile)
+               if self.debugging:
+                       print cmd
+                       cmd = 'set -x; ' + cmd
+               return cmd
+
+
+def makepipeline(infile, steps, outfile):
+       # Build a list with for each command:
+       # [input filename or '', command string, kind, output filename or '']
+       
+       list = []
+       for cmd, kind in steps:
+               list.append(['', cmd, kind, ''])
+       #
+       # Make sure there is at least one step
+       #
+       if list == []:
+               list.append(['', 'cat', '--', ''])
+       #
+       # Take care of the input and output ends
+       #
+       [cmd, kind] = list[0][1:3]
+       if kind[0] == 'f' and not infile:
+               list.insert(0, ['', 'cat', '--', ''])
+       list[0][0] = infile
+       #
+       [cmd, kind] = list[-1][1:3]
+       if kind[1] == 'f' and not outfile:
+               list.append(['', 'cat', '--', ''])
+       list[-1][-1] = outfile
+       #
+       # Invent temporary files to connect stages that need files
+       #
+       garbage = []
+       for i in range(1, len(list)):
+               lkind = list[i-1][2]
+               rkind = list[i][2]
+               if lkind[1] == 'f' or rkind[0] == 'f':
+                       temp = tempfile.mktemp()
+                       garbage.append(temp)
+                       list[i-1][-1] = list[i][0] = temp
+       #
+       for item in list:
+               [inf, cmd, kind, outf] = item
+               if kind[1] == 'f':
+                       cmd = 'OUT=' + quote(outf) + '; ' + cmd
+               if kind[0] == 'f':
+                       cmd = 'IN=' + quote(inf) + '; ' + cmd
+               if kind[0] == '-' and inf:
+                       cmd = cmd + ' <' + quote(inf)
+               if kind[1] == '-' and outf:
+                       cmd = cmd + ' >' + quote(outf)
+               item[1] = cmd
+       #
+       cmdlist = list[0][1]
+       for item in list[1:]:
+               [cmd, kind] = item[1:3]
+               if item[0] == '':
+                       if 'f' in kind:
+                               cmd = '{ ' + cmd + '; }'
+                       cmdlist = cmdlist + ' |\n' + cmd
+               else:
+                       cmdlist = cmdlist + '\n' + cmd
+       #
+       if garbage:
+               rmcmd = 'rm -f'
+               for file in garbage:
+                       rmcmd = rmcmd + ' ' + quote(file)
+               trapcmd = 'trap ' + quote(rmcmd + '; exit') + ' 1 2 3 13 14 15'
+               cmdlist = trapcmd + '\n' + cmdlist + '\n' + rmcmd
+       #
+       return cmdlist
+
+
+# Reliably quote a string as a single argument for /bin/sh
+
+_safechars = string.letters + string.digits + '!@%_-+=:,./'    # Safe unquoted
+_funnychars = '"`$\\'                          # Unsafe inside "double quotes"
+
+def quote(file):
+       for c in file:
+               if c not in _safechars:
+                       break
+       else:
+               return file
+       if '\'' not in file:
+               return '\'' + file + '\''
+       res = ''
+       for c in file:
+               if c in _funnychars:
+                       c = '\\' + c
+               res = res + c
+       return '"' + res + '"'
+
+
+# Small test program and example
+
+def test():
+       import os
+       print 'Testing...'
+       t = Template().init()
+       t.append('togif $IN $OUT', 'ff')
+       t.append('giftoppm', '--')
+       t.append('ppmtogif >$OUT', '-f')
+       t.append('fromgif $IN $OUT', 'ff')
+       t.debug(1)
+       FILE = '/usr/local/images/rgb/rogues/guido.rgb'
+       t.copy(FILE, '@temp')
+       print 'Done.'
diff --git a/Lib/plat-irix5/torgb.py b/Lib/plat-irix5/torgb.py
new file mode 100755 (executable)
index 0000000..e46aca3
--- /dev/null
@@ -0,0 +1,91 @@
+# Convert "arbitrary" image files to rgb files (SGI's image format).
+# Input may be compressed.
+# The uncompressed file type may be PBM, PGM, PPM, GIF, TIFF, or Sun raster.
+# An exception is raised if the file is not of a recognized type.
+# Returned filename is either the input filename or a temporary filename;
+# in the latter case the caller must ensure that it is removed.
+# Other temporary files used are removed by the function.
+
+import os
+import tempfile
+import pipes
+import imghdr
+
+table = {}
+
+t = pipes.Template().init()
+t.append('fromppm $IN $OUT', 'ff')
+table['ppm'] = t
+
+t = pipes.Template().init()
+t.append('pnmtoppm', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['pnm'] = t
+table['pgm'] = t
+table['pbm'] = t
+
+t = pipes.Template().init()
+t.append('fromgif $IN $OUT', 'ff')
+table['gif'] = t
+
+t = pipes.Template().init()
+t.append('tifftopnm', '--')
+t.append('(PATH=$PATH:/ufs/guido/bin/sgi; exec pnmtoppm)', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['tiff'] = t
+
+t = pipes.Template().init()
+t.append('rasttopnm', '--')
+t.append('pnmtoppm', '--')
+t.append('fromppm $IN $OUT', 'ff')
+table['rast'] = t
+
+uncompress = pipes.Template().init()
+uncompress.append('uncompress', '--')
+
+
+error = 'torgb.error' # Exception
+
+def torgb(filename):
+       temps = []
+       ret = None
+       try:
+               ret = _torgb(filename, temps)
+       finally:
+               for temp in temps[:]:
+                       if temp <> ret:
+                               try:
+                                       os.unlink(temp)
+                               except os.error:
+                                       pass
+                               temps.remove(temp)
+       return ret
+
+def _torgb(filename, temps):
+       if filename[-2:] == '.Z':
+               fname = tempfile.mktemp()
+               temps.append(fname)
+               sts = uncompress.copy(filename, fname)
+               if sts:
+                       raise error, filename + ': uncompress failed'
+       else:
+               fname = filename
+       try:
+               ftype = imghdr.what(fname)
+       except IOError, msg:
+               if type(msg) == type(()) and len(msg) == 2 and \
+                       type(msg[0]) == type(0) and type(msg[1]) == type(''):
+                       msg = msg[1]
+               if type(msg) <> type(''):
+                       msg = `msg`
+               raise error, filename + ': ' + msg
+       if ftype == 'rgb':
+               return fname
+       if ftype == None or not table.has_key(ftype):
+               raise error, \
+                       filename + ': unsupported image file type ' + `ftype`
+       temp = tempfile.mktemp()
+       sts = table[ftype].copy(fname, temp)
+       if sts:
+               raise error, filename + ': conversion to rgb failed'
+       return temp
index 6386a9549dd94f2b47c4f3ebeb21886afcfb1f4f..cc60678bfb323591dda2d38c5134d76e011a45d1 100644 (file)
@@ -163,3 +163,15 @@ def expandtabs(s, tabsize):
                        res = res + line
                        line = ''
        return res + line
+
+
+# Try importing optional built-in module "strop" -- if it exists,
+# it redefines some string operations that are 100-1000 times faster.
+# The manipulation with index_error is needed for compatibility.
+
+try:
+       from strop import *
+       from strop import index
+       index_error = ValueError
+except ImportError:
+       pass # Use the original, slow versions
index 6386a9549dd94f2b47c4f3ebeb21886afcfb1f4f..cc60678bfb323591dda2d38c5134d76e011a45d1 100644 (file)
@@ -163,3 +163,15 @@ def expandtabs(s, tabsize):
                        res = res + line
                        line = ''
        return res + line
+
+
+# Try importing optional built-in module "strop" -- if it exists,
+# it redefines some string operations that are 100-1000 times faster.
+# The manipulation with index_error is needed for compatibility.
+
+try:
+       from strop import *
+       from strop import index
+       index_error = ValueError
+except ImportError:
+       pass # Use the original, slow versions
diff --git a/Lib/toaiff.py b/Lib/toaiff.py
new file mode 100644 (file)
index 0000000..adb2e61
--- /dev/null
@@ -0,0 +1,101 @@
+# Convert "arbitrary" sound files to AIFF files (Apple and SGI's audio format).
+# Input may be compressed.
+# Uncompressed file type may be AIFF, WAV, VOC, 8SVX, NeXT/Sun, and others.
+# An exception is raised if the file is not of a recognized type.
+# Returned filename is either the input filename or a temporary filename;
+# in the latter case the caller must ensure that it is removed.
+# Other temporary files used are removed by the function.
+
+import os
+import tempfile
+import pipes
+import sndhdr
+
+table = {}
+
+t = pipes.Template().init()
+t.append('sox -t au - -t aiff -r 8000 -', '--')
+table['au'] = t
+
+# XXX The following is actually sub-optimal.
+# XXX The HCOM sampling rate can be 22k, 22k/2, 22k/3 or 22k/4.
+# XXX We must force the output sampling rate else the SGI won't play
+# XXX files sampled at 5.5k or 7.333k; however this means that files
+# XXX sampled at 11k are unnecessarily expanded.
+# XXX Similar comments apply to some other file types.
+t = pipes.Template().init()
+t.append('sox -t hcom - -t aiff -r 22050 -', '--')
+table['hcom'] = t
+
+t = pipes.Template().init()
+t.append('sox -t voc - -t aiff -r 11025 -', '--')
+table['voc'] = t
+
+t = pipes.Template().init()
+t.append('sox -t wav - -t aiff -', '--')
+table['wav'] = t
+
+t = pipes.Template().init()
+t.append('sox -t 8svx - -t aiff -r 16000 -', '--')
+table['8svx'] = t
+
+t = pipes.Template().init()
+t.append('sox -t sndt - -t aiff -r 16000 -', '--')
+table['sndt'] = t
+
+t = pipes.Template().init()
+t.append('sox -t sndr - -t aiff -r 16000 -', '--')
+table['sndr'] = t
+
+uncompress = pipes.Template().init()
+uncompress.append('uncompress', '--')
+
+
+error = 'toaiff.error' # Exception
+
+def toaiff(filename):
+       temps = []
+       ret = None
+       try:
+               ret = _toaiff(filename, temps)
+       finally:
+               for temp in temps[:]:
+                       if temp <> ret:
+                               try:
+                                       os.unlink(temp)
+                               except os.error:
+                                       pass
+                               temps.remove(temp)
+       return ret
+
+def _toaiff(filename, temps):
+       if filename[-2:] == '.Z':
+               fname = tempfile.mktemp()
+               temps.append(fname)
+               sts = uncompress.copy(filename, fname)
+               if sts:
+                       raise error, filename + ': uncomress failed'
+       else:
+               fname = filename
+       try:
+               ftype = sndhdr.whathdr(fname)
+               if ftype:
+                       ftype = ftype[0] # All we're interested in
+       except IOError:
+               if type(msg) == type(()) and len(msg) == 2 and \
+                       type(msg[0]) == type(0) and type(msg[1]) == type(''):
+                       msg = msg[1]
+               if type(msg) <> type(''):
+                       msg = `msg`
+               raise error, filename + ': ' + msg
+       if ftype == 'aiff':
+               return fname
+       if ftype == None or not table.has_key(ftype):
+               raise error, \
+                       filename + ': unsupported audio file type ' + `ftype`
+       temp = tempfile.mktemp()
+       temps.append(temp)
+       sts = table[ftype].copy(fname, temp)
+       if sts:
+               raise error, filename + ': conversion to aiff failed'
+       return temp
diff --git a/Lib/tzparse.py b/Lib/tzparse.py
new file mode 100644 (file)
index 0000000..67c94de
--- /dev/null
@@ -0,0 +1,76 @@
+# Parse a timezone specification.
+# XXX Unfinished.
+# XXX Only the typical form "XXXhhYYY;ddd/hh,ddd/hh" is currently supported.
+
+tzpat = '^\([A-Z][A-Z][A-Z]\)\([-+]?[0-9]+\)\([A-Z][A-Z][A-Z]\);' + \
+         '\([0-9]+\)/\([0-9]+\),\([0-9]+\)/\([0-9]+\)$'
+
+tzprog = None
+
+def tzparse(tzstr):
+       global tzprog
+       if tzprog == None:
+               import regex
+               tzprog = regex.compile(tzpat)
+       if not tzprog.match(tzstr):
+               raise ValueError, 'not the TZ syntax I understand'
+       regs = tzprog.regs
+       subs = []
+       for i in range(1, 8):
+               a, b = regs[i]
+               subs.append(tzstr[a:b])
+       for i in (1, 3, 4, 5, 6):
+               subs[i] = eval(subs[i])
+       [tzname, delta, dstname, daystart, hourstart, dayend, hourend] = subs
+       return (tzname, delta, dstname, daystart, hourstart, dayend, hourend)
+
+def tzlocaltime(time, params):
+       import calendar
+       (tzname, delta, dstname, daystart, hourstart, dayend, hourend) = params
+       year, month, days, hours, mins, secs, yday, wday = \
+               calendar.gmtime(time - delta*3600)
+       if (daystart, hourstart) <= (yday+1, hours) < (dayend, hourend):
+               tzname = dstname
+               hours = hours + 1
+       return year, month, days, hours, mins, secs, yday, wday, tzname
+
+def tzset():
+       global tzparams, timezone, altzone, daylight, tzname
+       import os
+       tzstr = os.environ['TZ']
+       tzparams = tzparse(tzstr)
+       timezone = tzparams[1] * 3600
+       altzone = timezone + 3600
+       daylight = 1
+       tzname = tzparams[0], tzparams[2]
+
+def isdst(time):
+       import calendar
+       (tzname, delta, dstname, daystart, hourstart, dayend, hourend) = \
+               tzparams
+       year, month, days, hours, mins, secs, yday, wday = \
+               calendar.gmtime(time - delta*3600)
+       return (daystart, hourstart) <= (yday+1, hours) < (dayend, hourend)
+
+tzset()
+
+def localtime(time):
+       return tzlocaltime(time, tzparams)
+
+def test():
+       from calendar import asctime, gmtime
+       import time, sys
+       now = time.time()
+       x = localtime(now)
+       print 'now =', now, '=', asctime(x[:-1]), x[-1]
+       now = now - now % (24*3600)
+       if sys.argv[1:]: now = now + eval(sys.argv[1])
+       x = gmtime(now)
+       print 'gmtime =', now, '=', asctime(x), 'yday =', x[-2]
+       jan1 = now - x[-2]*24*3600
+       x = localtime(jan1)
+       print 'jan1 =', jan1, '=', asctime(x[:-1]), x[-1]
+       for d in range(85, 95) + range(265, 275):
+               t = jan1 + d*24*3600
+               x = localtime(t)
+               print 'd =', d, 't =', t, '=', asctime(x[:-1]), x[-1]
index 2ce5f8f79ad4f8d576e377beaa9ab7da264f64e5..662390483a1fd98cb1703027154dee9a4e4578e2 100644 (file)
 #      whrandom.random()       yields double precision random numbers 
 #                              uniformly distributed between 0 and 1.
 #
-#      whrandom.seed()         must be called before whrandom.random()
+#      whrandom.seed(x, y, z)  must be called before whrandom.random()
 #                              to seed the generator
+#
+#      There is also an interface to create multiple independent
+#      random generators, and to choose from other ranges.
 
 
 #      Translated by Guido van Rossum from C source provided by
 #      Adrian Baddeley.
 
 
-# The seed
-#
-_seed = [0, 0, 0]
-
-
-# Set the seed
-#
-def seed(x, y, z):
-       _seed[:] = [x, y, z]
-
-
-# Return the next random number in the range [0.0 .. 1.0)
-#
-def random():
-       from math import floor          # floor() function
+class whrandom:
+       #
+       # Initialize an instance.
+       # Without arguments, initialize from current time.
+       # With arguments (x, y, z), initialize from them.
        #
-       [x, y, z] = _seed
-       x = 171 * (x % 177) - 2 * (x/177)
-       y = 172 * (y % 176) - 35 * (y/176)
-       z = 170 * (z % 178) - 63 * (z/178)
+       def init(self, *xyz):
+               if not xyz:
+                       # Initialize from current time
+                       import time
+                       t = time.time()
+                       t, x = divmod(t, 256)
+                       t, y = divmod(t, 256)
+                       t, z = divmod(t, 256)
+               else:
+                       # Initialize from arguments (x, y, z)
+                       x, y, z = xyz
+               self.seed(x, y, z)
+               return self
        #
-       if x < 0: x = x + 30269
-       if y < 0: y = y + 30307
-       if z < 0: z = z + 30323
+       # Set the seed from (x, y, z).
+       # These must be integers in the range [0, 256).
        #
-       _seed[:] = [x, y, z]
+       def seed(self, *xyz):
+               if type(xyz) <> type(()) or len(xyz) <> 3:
+                       raise TypeError, '3 seeds required'
+               x, y, z = xyz
+               if not type(x) == type(y) == type(z) == type(0):
+                       raise TypeError, 'seeds must be integers'
+               if not 0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256:
+                       raise ValueError, 'seeds must be in range(0, 256)'
+               self._seed = xyz
        #
-       term = float(x)/30269.0 + float(y)/30307.0 + float(z)/30323.0
-       rand = term - floor(term)
+       # Get the next random number in the range [0.0, 1.0).
        #
-       if rand >= 1.0: rand = 0.0      # floor() inaccuracy?
+       def random(self):
+               x, y, z = self._seed
+               #
+               x1, x2 = divmod(x, 177)
+               y1, y2 = divmod(y, 176)
+               z1, z2 = divmod(z, 178)
+               #
+               x = (171 * x2 -  2 * x1) % 30269
+               y = (172 * y2 - 35 * y1) % 30307
+               z = (170 * z2 - 63 * z1) % 30323
+               #
+               self._seed = x, y, z
+               #
+               return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
        #
-       return rand
+       # Get a random number in the range [a, b).
+       #
+       def uniform(self, a, b):
+               return a + (b-a) * self.random()
+       #
+       # Get a random integer in the range [a, b] including both end points.
+       #
+       def randint(self, a, b):
+               return a + int(self.random() * (b+1-a))
+       #
+       # Choose a random element from a non-empty sequence.
+       #
+       def choice(self, seq):
+               return seq[int(self.random() * len(seq))]
 
 
 # Initialize from the current time
 #
-def init():
-       import time
-       t = time.time()
-       seed(t%256, t/256%256, t/65536%256)
-
-
-# Make sure the generator is preset to a nonzero value
-#
-init()
+_inst = whrandom().init()
+seed = _inst.seed
+random = _inst.random
+uniform = _inst.uniform
+randint = _inst.randint
+choice = _inst.choice