From c636014c430620325f8d213e9ba10d925991b8d7 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 13 Oct 1990 19:23:40 +0000 Subject: [PATCH] Initial revision --- Lib/calendar.py | 213 +++++++++++++++++ Lib/cmp.py | 61 +++++ Lib/cmpcache.py | 74 ++++++ Lib/commands.py | 73 ++++++ Lib/dircache.py | 36 +++ Lib/dircmp.py | 215 +++++++++++++++++ Lib/dump.py | 63 +++++ Lib/getopt.py | 47 ++++ Lib/irix5/DEVICE.py | 423 +++++++++++++++++++++++++++++++++ Lib/irix5/GL.py | 365 ++++++++++++++++++++++++++++ Lib/irix5/auds.py | 106 +++++++++ Lib/irix5/panel.py | 281 ++++++++++++++++++++++ Lib/irix5/panelparser.py | 128 ++++++++++ Lib/lib-old/dump.py | 63 +++++ Lib/lib-old/rand.py | 12 + Lib/lib-old/util.py | 9 + Lib/lib-stdwin/anywin.py | 14 ++ Lib/lib-stdwin/dirwin.py | 28 +++ Lib/lib-stdwin/filewin.py | 31 +++ Lib/lib-stdwin/gwin.py | 118 +++++++++ Lib/lib-stdwin/listwin.py | 47 ++++ Lib/lib-stdwin/rect.py | 87 +++++++ Lib/lib-stdwin/stdwinevents.py | 36 +++ Lib/lib-stdwin/tablewin.py | 237 ++++++++++++++++++ Lib/lib-stdwin/textwin.py | 119 ++++++++++ Lib/plat-irix5/DEVICE.py | 423 +++++++++++++++++++++++++++++++++ Lib/plat-irix5/GL.py | 365 ++++++++++++++++++++++++++++ Lib/plat-irix5/panel.py | 281 ++++++++++++++++++++++ Lib/plat-irix5/panelparser.py | 128 ++++++++++ Lib/poly.py | 55 +++++ Lib/posixpath.py | 124 ++++++++++ Lib/rand.py | 12 + Lib/shutil.py | 70 ++++++ Lib/statcache.py | 90 +++++++ Lib/stdwin/anywin.py | 14 ++ Lib/stdwin/dirwin.py | 28 +++ Lib/stdwin/filewin.py | 31 +++ Lib/stdwin/gwin.py | 118 +++++++++ Lib/stdwin/listwin.py | 47 ++++ Lib/stdwin/rect.py | 87 +++++++ Lib/stdwin/stdwinevents.py | 36 +++ Lib/stdwin/tablewin.py | 237 ++++++++++++++++++ Lib/stdwin/textwin.py | 119 ++++++++++ Lib/string.py | 129 ++++++++++ Lib/stringold.py | 129 ++++++++++ Lib/util.py | 9 + Lib/whrandom.py | 74 ++++++ 47 files changed, 5492 insertions(+) create mode 100644 Lib/calendar.py create mode 100644 Lib/cmp.py create mode 100644 Lib/cmpcache.py create mode 100644 Lib/commands.py create mode 100644 Lib/dircache.py create mode 100644 Lib/dircmp.py create mode 100644 Lib/dump.py create mode 100644 Lib/getopt.py create mode 100755 Lib/irix5/DEVICE.py create mode 100755 Lib/irix5/GL.py create mode 100755 Lib/irix5/auds.py create mode 100755 Lib/irix5/panel.py create mode 100755 Lib/irix5/panelparser.py create mode 100644 Lib/lib-old/dump.py create mode 100644 Lib/lib-old/rand.py create mode 100644 Lib/lib-old/util.py create mode 100644 Lib/lib-stdwin/anywin.py create mode 100644 Lib/lib-stdwin/dirwin.py create mode 100644 Lib/lib-stdwin/filewin.py create mode 100644 Lib/lib-stdwin/gwin.py create mode 100644 Lib/lib-stdwin/listwin.py create mode 100644 Lib/lib-stdwin/rect.py create mode 100644 Lib/lib-stdwin/stdwinevents.py create mode 100644 Lib/lib-stdwin/tablewin.py create mode 100644 Lib/lib-stdwin/textwin.py create mode 100755 Lib/plat-irix5/DEVICE.py create mode 100755 Lib/plat-irix5/GL.py create mode 100755 Lib/plat-irix5/panel.py create mode 100755 Lib/plat-irix5/panelparser.py create mode 100644 Lib/poly.py create mode 100644 Lib/posixpath.py create mode 100644 Lib/rand.py create mode 100644 Lib/shutil.py create mode 100644 Lib/statcache.py create mode 100755 Lib/stdwin/anywin.py create mode 100755 Lib/stdwin/dirwin.py create mode 100755 Lib/stdwin/filewin.py create mode 100755 Lib/stdwin/gwin.py create mode 100755 Lib/stdwin/listwin.py create mode 100755 Lib/stdwin/rect.py create mode 100755 Lib/stdwin/stdwinevents.py create mode 100755 Lib/stdwin/tablewin.py create mode 100755 Lib/stdwin/textwin.py create mode 100644 Lib/string.py create mode 100644 Lib/stringold.py create mode 100644 Lib/util.py create mode 100644 Lib/whrandom.py diff --git a/Lib/calendar.py b/Lib/calendar.py new file mode 100644 index 00000000000..49e8e632e42 --- /dev/null +++ b/Lib/calendar.py @@ -0,0 +1,213 @@ +# module calendar + +############################## +# Calendar support functions # +############################## + +# This is based on UNIX ctime() et al. (also Standard C and POSIX) +# Subtle but crucial differences: +# - the order of the elements of a 'struct tm' differs, to ease sorting +# - months numbers are 1-12, not 0-11; month arrays have a dummy element 0 +# - 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) +day_0 = 3 # The epoch begins on a Thursday (Monday = 0) + +# Return 1 for leap years, 0 for non-leap years +def isleap(year): + return year % 4 = 0 and (year % 100 <> 0 or year % 400 = 0) + +# Constants for months referenced later +January = 1 +February = 2 + +# Number of days per month (except for February in leap years) +mdays = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) + +# Exception raised for bad input (with string parameter for details) +error = 'calendar error' + +# Turn seconds since epoch into calendar time +def gmtime(secs): + if secs < 0: raise error, 'negative input to gmtime()' + mins, secs = divmod(secs, 60) + hours, mins = divmod(mins, 60) + days, hours = divmod(hours, 24) + wday = (days + day_0) % 7 + year = epoch + # XXX Most of the following loop can be replaced by one division + while 1: + yd = 365 + isleap(year) + if days < yd: break + days = days - yd + year = year + 1 + yday = days + month = January + while 1: + md = mdays[month] + (month = February and isleap(year)) + if days < md: break + days = days - md + month = month + 1 + return year, month, days + 1, hours, mins, secs, yday, wday + # XXX Week number also? + +# Return number of leap years in range [y1, y2) +# Assume y1 <= y2 and no funny (non-leap century) years +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 +def mktime(year, month, day, hours, mins, secs): + days = day - 1 + for m in range(January, month): days = days + mdays[m] + if isleap(year) and month > February: days = days+1 + days = days + (year-epoch)*365 + leapdays(epoch, year) + return ((days*24 + hours)*60 + mins)*60 + secs + +# Full and abbreviated names of weekdays +day_name = ('Monday', 'Tuesday', 'Wednesday', 'Thursday') +day_name = day_name + ('Friday', 'Saturday', 'Sunday') +day_abbr = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun') + +# Full and abbreviated of months (1-based arrays!!!) +month_name = ('', 'January', 'February', 'March', 'April') +month_name = month_name + ('May', 'June', 'July', 'August') +month_name = month_name + ('September', 'October', 'November', 'December') +month_abbr = (' ', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun') +month_abbr = month_abbr + ('Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') + +# Zero-fill string to two positions (helper for asctime()) +def dd(s): + while len(s) < 2: s = '0' + s + return s + +# Blank-fill string to two positions (helper for asctime()) +def zd(s): + while len(s) < 2: s = ' ' + s + return s + +# Turn calendar time as returned by gmtime() into a string +# (the yday parameter is for compatibility with gmtime()) +def asctime(year, month, day, hours, mins, secs, yday, wday): + s = day_abbr[wday] + ' ' + month_abbr[month] + ' ' + zd(`day`) + s = s + ' ' + dd(`hours`) + ':' + dd(`mins`) + ':' + dd(`secs`) + 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) + +# Local time ignores DST issues for now -- adjust 'timezone' to fake it +def localtime(secs): + return gmtime(secs - timezone*60) + +# UNIX-style ctime (except it doesn't append '\n'!) +def ctime(secs): + return asctime(localtime(secs)) + +###################### +# Non-UNIX additions # +###################### + +# Calendar printing etc. + +# Return weekday (0-6 ~ Mon-Sun) for year (1970-...), month (1-12), day (1-31) +def weekday(year, month, day): + secs = mktime(year, month, day, 0, 0, 0) + days = secs / (24*60*60) + return (days + day_0) % 7 + +# Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for year, month +def monthrange(year, month): + day1 = weekday(year, month, 1) + ndays = mdays[month] + (month = February and isleap(year)) + return day1, ndays + +# Return a matrix representing a month's calendar +# Each row represents a week; days outside this month are zero +def _monthcalendar(year, month): + day1, ndays = monthrange(year, month) + rows = [] + r7 = range(7) + day = 1 - day1 + while day <= ndays: + row = [0, 0, 0, 0, 0, 0, 0] + for i in r7: + if 1 <= day <= ndays: row[i] = day + day = day + 1 + rows.append(row) + return rows + +# Caching interface to _monthcalendar +mc_cache = {} +def monthcalendar(year, month): + key = `year` + month_abbr[month] + try: + return mc_cache[key] + except RuntimeError: + mc_cache[key] = ret = _monthcalendar(year, month) + return ret + +# Center a string in a field +def center(str, width): + n = width - len(str) + if n < 0: return str + return ' '*(n/2) + str + ' '*(n-n/2) + +# XXX The following code knows that print separates items with space! + +# Print a single week (no newline) +def prweek(week, width): + for day in week: + if day = 0: print ' '*width, + else: + if width > 2: print ' '*(width-3), + if day < 10: print '', + print day, + +# Return a header for a week +def weekheader(width): + str = '' + for i in range(7): + if str: str = str + ' ' + str = str + day_abbr[i%7][:width] + return str + +# Print a month's calendar +def prmonth(year, month): + print weekheader(3) + for week in monthcalendar(year, month): + prweek(week, 3) + print + +# Spacing between month columns +spacing = ' ' + +# 3-column formatting for year calendars +def format3c(a, b, c): + print center(a, 20), spacing, center(b, 20), spacing, center(c, 20) + +# Print a year's calendar +def prcal(year): + header = weekheader(2) + format3c('', `year`, '') + for q in range(January, January+12, 3): + print + format3c(month_name[q], month_name[q+1], month_name[q+2]) + format3c(header, header, header) + data = [] + height = 0 + for month in range(q, q+3): + cal = monthcalendar(year, month) + if len(cal) > height: height = len(cal) + data.append(cal) + for i in range(height): + for cal in data: + if i >= len(cal): + print ' '*20, + else: + prweek(cal[i], 2) + print spacing, + print diff --git a/Lib/cmp.py b/Lib/cmp.py new file mode 100644 index 00000000000..434caee06c2 --- /dev/null +++ b/Lib/cmp.py @@ -0,0 +1,61 @@ +# Module 'cmp' + +# Efficiently compare files, boolean outcome only (equal / not equal). + +# Tricks (used in this order): +# - Files with identical type, size & mtime are assumed to be clones +# - Files with different type or size cannot be identical +# - We keep a cache of outcomes of earlier comparisons +# - We don't fork a process to run 'cmp' but read the files ourselves + +import posix + +cache = {} + +def cmp(f1, f2): # Compare two files, use the cache if possible. + # Return 1 for identical files, 0 for different. + # Raise exceptions if either file could not be statted, read, etc. + s1, s2 = sig(posix.stat(f1)), sig(posix.stat(f2)) + if s1[0] <> 8 or s2[0] <> 8: + # Either is a not a plain file -- always report as different + return 0 + if s1 = s2: + # type, size & mtime match -- report same + return 1 + if s1[:2] <> s2[:2]: # Types or sizes differ, don't bother + # types or sizes differ -- report different + return 0 + # same type and size -- look in the cache + key = f1 + ' ' + f2 + try: + cs1, cs2, outcome = cache[key] + # cache hit + if s1 = cs1 and s2 = cs2: + # cached signatures match + return outcome + # stale cached signature(s) + except RuntimeError: + # cache miss + pass + # really compare + outcome = do_cmp(f1, f2) + cache[key] = s1, s2, outcome + return outcome + +def sig(st): # Return signature (i.e., type, size, mtime) from raw stat data + # 0-5: st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid + # 6-9: st_size, st_atime, st_mtime, st_ctime + type = st[0] / 4096 + size = st[6] + mtime = st[8] + return type, size, mtime + +def do_cmp(f1, f2): # Compare two files, really + bufsize = 8096 # Could be tuned + fp1 = open(f1, 'r') + fp2 = open(f2, 'r') + while 1: + b1 = fp1.read(bufsize) + b2 = fp2.read(bufsize) + if b1 <> b2: return 0 + if not b1: return 1 diff --git a/Lib/cmpcache.py b/Lib/cmpcache.py new file mode 100644 index 00000000000..a47a4fd5aca --- /dev/null +++ b/Lib/cmpcache.py @@ -0,0 +1,74 @@ +# Module 'cmpcache' +# +# Efficiently compare files, boolean outcome only (equal / not equal). +# +# Tricks (used in this order): +# - Use the statcache module to avoid statting files more than once +# - Files with identical type, size & mtime are assumed to be clones +# - Files with different type or size cannot be identical +# - We keep a cache of outcomes of earlier comparisons +# - We don't fork a process to run 'cmp' but read the files ourselves +# +# XXX There is a dependency on constants in here. + +import posix +import statcache + + +# The cache. +# +cache = {} + + +# Compare two files, use the cache if possible. +# May raise posix.error if a stat or open of either fails. +# +def cmp(f1, f2): + # Return 1 for identical files, 0 for different. + # Raise exceptions if either file could not be statted, read, etc. + s1, s2 = sig(statcache.stat(f1)), sig(statcache.stat(f2)) + if s1[0] <> 8 or s2[0] <> 8: # XXX 8 is S_IFREG in + # Either is a not a plain file -- always report as different + return 0 + if s1 = s2: + # type, size & mtime match -- report same + return 1 + if s1[:2] <> s2[:2]: # Types or sizes differ, don't bother + # types or sizes differ -- report different + return 0 + # same type and size -- look in the cache + key = f1 + ' ' + f2 + if cache.has_key(key): + cs1, cs2, outcome = cache[key] + # cache hit + if s1 = cs1 and s2 = cs2: + # cached signatures match + return outcome + # stale cached signature(s) + # really compare + outcome = do_cmp(f1, f2) + cache[key] = s1, s2, outcome + return outcome + +# Return signature (i.e., type, size, mtime) from raw stat data. +# +def sig(st): + # 0-5: st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid + # 6-9: st_size, st_atime, st_mtime, st_ctime + type = st[0] / 4096 # XXX dependent on S_IFMT in + size = st[6] + mtime = st[8] + return type, size, mtime + +# Compare two files, really. +# +def do_cmp(f1, f2): + #print ' cmp', f1, f2 # XXX remove when debugged + bufsize = 8096 # Could be tuned + fp1 = open(f1, 'r') + fp2 = open(f2, 'r') + while 1: + b1 = fp1.read(bufsize) + b2 = fp2.read(bufsize) + if b1 <> b2: return 0 + if not b1: return 1 diff --git a/Lib/commands.py b/Lib/commands.py new file mode 100644 index 00000000000..145f5dbdc4f --- /dev/null +++ b/Lib/commands.py @@ -0,0 +1,73 @@ +# Module 'commands' +# +# Various tools for executing commands and looking at their output and status. + +import rand +import posix +import path + + +# Get 'ls -l' status for an object into a string +# +def getstatus(file): + return getoutput('ls -ld' + mkarg(file)) + + +# Get the output from a shell command into a string. +# The exit status is ignored; a trailing newline is stripped. +# Assume the command will work with ' >tempfile 2>&1' appended. +# XXX This should use posix.popen() instead, should it exist. +# +def getoutput(cmd): + return getstatusoutput(cmd)[1] + + +# Ditto but preserving the exit status. +# Returns a pair (sts, output) +# +def getstatusoutput(cmd): + tmp = '/usr/tmp/wdiff' + `rand.rand()` + sts = -1 + try: + sts = posix.system(cmd + ' >' + tmp + ' 2>&1') + text = readfile(tmp) + finally: + altsts = posix.system('rm -f ' + tmp) + if text[-1:] = '\n': text = text[:-1] + return sts, text + + +# Return a string containing a file's contents. +# +def readfile(fn): + fp = open(fn, 'r') + a = '' + n = 8096 + while 1: + b = fp.read(n) + if not b: break + a = a + b + return a + + +# Make command argument from directory and pathname (prefix space, add quotes). +# +def mk2arg(head, x): + return mkarg(path.cat(head, x)) + + +# Make a shell command argument from a string. +# Two strategies: enclose in single quotes if it contains none; +# otherwis, enclose in double quotes and prefix quotable characters +# with backslash. +# +def mkarg(x): + if '\'' not in x: + return ' \'' + x + '\'' + s = ' "' + for c in x: + if c in '\\$"': + s = s + '\\' + s = s + c + s = s + '"' + return s diff --git a/Lib/dircache.py b/Lib/dircache.py new file mode 100644 index 00000000000..b40f76e8a2c --- /dev/null +++ b/Lib/dircache.py @@ -0,0 +1,36 @@ +# Module 'dircache' +# +# Return a sorted list of the files in a POSIX directory, using a cache +# to avoid reading the directory more often than necessary. +# Also contains a subroutine to append slashes to directories. + +import posix +import path + +cache = {} + +def listdir(path): # List directory contents, using cache + try: + cached_mtime, list = cache[path] + del cache[path] + except RuntimeError: + cached_mtime, list = -1, [] + try: + mtime = posix.stat(path)[8] + except posix.error: + return [] + if mtime <> cached_mtime: + try: + list = posix.listdir(path) + except posix.error: + return [] + list.sort() + cache[path] = mtime, list + return list + +opendir = listdir # XXX backward compatibility + +def annotate(head, list): # Add '/' suffixes to directories + for i in range(len(list)): + if path.isdir(path.cat(head, list[i])): + list[i] = list[i] + '/' diff --git a/Lib/dircmp.py b/Lib/dircmp.py new file mode 100644 index 00000000000..762a186095f --- /dev/null +++ b/Lib/dircmp.py @@ -0,0 +1,215 @@ +# Module 'dirmp' +# +# Defines a class to build directory diff tools on. + +import posix + +import path + +import dircache +import cmpcache +import statcache + + +# File type constants from . +# +S_IFDIR = 4 +S_IFREG = 8 + +# Extract the file type from a stat buffer. +# +def S_IFMT(st): return st[0] / 4096 + + +# Directory comparison class. +# +class dircmp(): + # + def new(dd, (a, b)): # Initialize + dd.a = a + dd.b = b + # Properties that caller may change before callingdd. run(): + dd.hide = ['.', '..'] # Names never to be shown + dd.ignore = ['RCS', 'tags'] # Names ignored in comparison + # + return dd + # + def run(dd): # Compare everything except common subdirectories + dd.a_list = filter(dircache.listdir(dd.a), dd.hide) + dd.b_list = filter(dircache.listdir(dd.b), dd.hide) + dd.a_list.sort() + dd.b_list.sort() + dd.phase1() + dd.phase2() + dd.phase3() + # + def phase1(dd): # Compute common names + dd.a_only = [] + dd.common = [] + for x in dd.a_list: + if x in dd.b_list: + dd.common.append(x) + else: + dd.a_only.append(x) + # + dd.b_only = [] + for x in dd.b_list: + if x not in dd.common: + dd.b_only.append(x) + # + def phase2(dd): # Distinguish files, directories, funnies + dd.common_dirs = [] + dd.common_files = [] + dd.common_funny = [] + # + for x in dd.common: + a_path = path.cat(dd.a, x) + b_path = path.cat(dd.b, x) + # + ok = 1 + try: + a_stat = statcache.stat(a_path) + except posix.error, why: + # print 'Can\'t stat', a_path, ':', why[1] + ok = 0 + try: + b_stat = statcache.stat(b_path) + except posix.error, why: + # print 'Can\'t stat', b_path, ':', why[1] + ok = 0 + # + if ok: + a_type = S_IFMT(a_stat) + b_type = S_IFMT(b_stat) + if a_type <> b_type: + dd.common_funny.append(x) + elif a_type = S_IFDIR: + dd.common_dirs.append(x) + elif a_type = S_IFREG: + dd.common_files.append(x) + else: + dd.common_funny.append(x) + else: + dd.common_funny.append(x) + # + def phase3(dd): # Find out differences between common files + xx = cmpfiles(dd.a, dd.b, dd.common_files) + dd.same_files, dd.diff_files, dd.funny_files = xx + # + def phase4(dd): # Find out differences between common subdirectories + # A new dircmp object is created for each common subdirectory, + # these are stored in a dictionary indexed by filename. + # The hide and ignore properties are inherited from the parent + dd.subdirs = {} + for x in dd.common_dirs: + a_x = path.cat(dd.a, x) + b_x = path.cat(dd.b, x) + dd.subdirs[x] = newdd = dircmp().new(a_x, b_x) + newdd.hide = dd.hide + newdd.ignore = dd.ignore + newdd.run() + # + def phase4_closure(dd): # Recursively call phase4() on subdirectories + dd.phase4() + for x in dd.subdirs.keys(): + dd.subdirs[x].phase4_closure() + # + def report(dd): # Print a report on the differences between a and b + # Assume that phases 1 to 3 have been executed + # Output format is purposely lousy + print 'diff', dd.a, dd.b + if dd.a_only: + print 'Only in', dd.a, ':', dd.a_only + if dd.b_only: + print 'Only in', dd.b, ':', dd.b_only + if dd.same_files: + print 'Identical files :', dd.same_files + if dd.diff_files: + print 'Differing files :', dd.diff_files + if dd.funny_files: + print 'Trouble with common files :', dd.funny_files + if dd.common_dirs: + print 'Common subdirectories :', dd.common_dirs + if dd.common_funny: + print 'Common funny cases :', dd.common_funny + # + def report_closure(dd): # Print reports on dd and on subdirs + # If phase 4 hasn't been done, no subdir reports are printed + dd.report() + try: + x = dd.subdirs + except NameError: + return # No subdirectories computed + for x in dd.subdirs.keys(): + print + dd.subdirs[x].report_closure() + # + def report_phase4_closure(dd): # Report and do phase 4 recursively + dd.report() + dd.phase4() + for x in dd.subdirs.keys(): + print + dd.subdirs[x].report_phase4_closure() + + +# Compare common files in two directories. +# Return: +# - files that compare equal +# - files that compare different +# - funny cases (can't stat etc.) +# +def cmpfiles(a, b, common): + res = ([], [], []) + for x in common: + res[cmp(path.cat(a, x), path.cat(b, x))].append(x) + return res + + +# Compare two files. +# Return: +# 0 for equal +# 1 for different +# 2 for funny cases (can't stat, etc.) +# +def cmp(a, b): + try: + if cmpcache.cmp(a, b): return 0 + return 1 + except posix.error: + return 2 + + +# Remove a list item. +# NB: This modifies the list argument. +# +def remove(list, item): + for i in range(len(list)): + if list[i] = item: + del list[i] + break + + +# Return a copy with items that occur in skip removed. +# +def filter(list, skip): + result = [] + for item in list: + if item not in skip: result.append(item) + return result + + +# Demonstration and testing. +# +def demo(): + import sys + import getopt + options, args = getopt.getopt(sys.argv[1:], 'r') + if len(args) <> 2: raise getopt.error, 'need exactly two args' + dd = dircmp().new(args[0], args[1]) + dd.run() + if ('-r', '') in options: + dd.report_phase4_closure() + else: + dd.report() + +# demo() diff --git a/Lib/dump.py b/Lib/dump.py new file mode 100644 index 00000000000..cecc275f75b --- /dev/null +++ b/Lib/dump.py @@ -0,0 +1,63 @@ +# Module 'dump' +# +# Print python code that reconstructs a variable. +# This only works in certain cases. +# +# It works fine for: +# - ints and floats (except NaNs and other weird things) +# - strings +# - compounds and lists, provided it works for all their elements +# - imported modules, provided their name is the module name +# +# It works for top-level dictionaries but not for dictionaries +# contained in other objects (could be made to work with some hassle +# though). +# +# It does not work for functions (all sorts), classes, class objects, +# windows, files etc. +# +# Finally, objects referenced by more than one name or contained in more +# than one other object lose their sharing property (this is bad for +# strings used as exception identifiers, for instance). + +# Dump a whole symbol table +# +def dumpsymtab(dict): + for key in dict.keys(): + dumpvar(key, dict[key]) + +# Dump a single variable +# +def dumpvar(name, x): + import sys + t = type(x) + if t = type({}): + print name, '= {}' + for key in x.keys(): + item = x[key] + if not printable(item): + print '#', + print name, '[', `key`, '] =', `item` + elif t in (type(''), type(0), type(0.0), type([]), type(())): + if not printable(x): + print '#', + print name, '=', `x` + elif t = type(sys): + print 'import', name, '#', x + else: + print '#', name, '=', x + +# check if a value is printable in a way that can be read back with input() +# +def printable(x): + t = type(x) + if t in (type(''), type(0), type(0.0)): + return 1 + if t in (type([]), type(())): + for item in x: + if not printable(item): + return 0 + return 1 + if x = {}: + return 1 + return 0 diff --git a/Lib/getopt.py b/Lib/getopt.py new file mode 100644 index 00000000000..ef72fbc0b22 --- /dev/null +++ b/Lib/getopt.py @@ -0,0 +1,47 @@ +# module getopt -- Standard command line processing. + +# Function getopt.getopt() has a different interface but provides the +# same functionality as the Unix getopt() function. + +# It has two arguments: the first should be argv[1:] (it doesn't want +# the script name), the second the string of option letters as passed +# to Unix getopt() (i.e., a string of allowable option letters, with +# options requiring an argument followed by a colon). + +# It raises the exception getopt.error with a string argument if it +# detects an error. + +# It returns two items: +# (1) a list of pairs (option, option_argument) giving the options in +# the order in which they were specified. (I'd use a dictionary +# but applications may depend on option order or multiple +# occurrences.) Boolean options have '' as option_argument. +# (2) the list of remaining arguments (may be empty). + +error = 'getopt error' + +def getopt(args, options): + list = [] + while args and args[0][0] = '-' and args[0] <> '-': + if args[0] = '--': + args = args[1:] + break + optstring, args = args[0][1:], args[1:] + while optstring <> '': + opt, optstring = optstring[0], optstring[1:] + if classify(opt, options): # May raise exception as well + if optstring = '': + if not args: + raise error, 'option -' + opt + ' requires argument' + optstring, args = args[0], args[1:] + optarg, optstring = optstring, '' + else: + optarg = '' + list.append('-' + opt, optarg) + return list, args + +def classify(opt, options): # Helper to check type of option + for i in range(len(options)): + if opt = options[i] <> ':': + return options[i+1:i+2] = ':' + raise error, 'option -' + opt + ' not recognized' diff --git a/Lib/irix5/DEVICE.py b/Lib/irix5/DEVICE.py new file mode 100755 index 00000000000..00eddfc13f7 --- /dev/null +++ b/Lib/irix5/DEVICE.py @@ -0,0 +1,423 @@ +#/************************************************************************** +# * * +# * Copyright (C) 1984, Silicon Graphics, Inc. * +# * * +# * These coded instructions, statements, and computer programs contain * +# * unpublished proprietary information of Silicon Graphics, Inc., and * +# * are protected by Federal copyright law. They may not be disclosed * +# * to third parties or copied or duplicated in any form, in whole or * +# * in part, without the prior written consent of Silicon Graphics, Inc. * +# * * +# **************************************************************************/ +#/* file with device definitions (see /usr/include/device.h) */ + +NULLDEV = 0 +BUTOFFSET = 1 +VALOFFSET = 256 +TIMOFFSET = 515 +XKBDOFFSET = 143 +INOFFSET = 1024 +OUTOFFSET = 1033 +BUTCOUNT = 190 +VALCOUNT = 27 +TIMCOUNT = 4 +XKBDCOUNT = 28 +INCOUNT = 8 +OUTCOUNT = 8 +# +# +# +# +BUT0 = 1 +BUT1 = 2 +BUT2 = 3 +BUT3 = 4 +BUT4 = 5 +BUT5 = 6 +BUT6 = 7 +BUT7 = 8 +BUT8 = 9 +BUT9 = 10 +BUT10 = 11 +BUT11 = 12 +BUT12 = 13 +BUT13 = 14 +BUT14 = 15 +BUT15 = 16 +BUT16 = 17 +BUT17 = 18 +BUT18 = 19 +BUT19 = 20 +BUT20 = 21 +BUT21 = 22 +BUT22 = 23 +BUT23 = 24 +BUT24 = 25 +BUT25 = 26 +BUT26 = 27 +BUT27 = 28 +BUT28 = 29 +BUT29 = 30 +BUT30 = 31 +BUT31 = 32 +BUT32 = 33 +BUT33 = 34 +BUT34 = 35 +BUT35 = 36 +BUT36 = 37 +BUT37 = 38 +BUT38 = 39 +BUT39 = 40 +BUT40 = 41 +BUT41 = 42 +BUT42 = 43 +BUT43 = 44 +BUT44 = 45 +BUT45 = 46 +BUT46 = 47 +BUT47 = 48 +BUT48 = 49 +BUT49 = 50 +BUT50 = 51 +BUT51 = 52 +BUT52 = 53 +BUT53 = 54 +BUT54 = 55 +BUT55 = 56 +BUT56 = 57 +BUT57 = 58 +BUT58 = 59 +BUT59 = 60 +BUT60 = 61 +BUT61 = 62 +BUT62 = 63 +BUT63 = 64 +BUT64 = 65 +BUT65 = 66 +BUT66 = 67 +BUT67 = 68 +BUT68 = 69 +BUT69 = 70 +BUT70 = 71 +BUT71 = 72 +BUT72 = 73 +BUT73 = 74 +BUT74 = 75 +BUT75 = 76 +BUT76 = 77 +BUT77 = 78 +BUT78 = 79 +BUT79 = 80 +BUT80 = 81 +BUT81 = 82 +BUT82 = 83 +MAXKBDBUT = 83 +BUT100 = 101 +BUT101 = 102 +BUT102 = 103 +BUT110 = 111 +BUT111 = 112 +BUT112 = 113 +BUT113 = 114 +BUT114 = 115 +BUT115 = 116 +BUT116 = 117 +BUT117 = 118 +BUT118 = 119 +BUT119 = 120 +BUT120 = 121 +BUT121 = 122 +BUT122 = 123 +BUT123 = 124 +BUT124 = 125 +BUT125 = 126 +BUT126 = 127 +BUT127 = 128 +BUT128 = 129 +BUT129 = 130 +BUT130 = 131 +BUT131 = 132 +BUT132 = 133 +BUT133 = 134 +BUT134 = 135 +BUT135 = 136 +BUT136 = 137 +BUT137 = 138 +BUT138 = 139 +BUT139 = 140 +BUT140 = 141 +BUT141 = 142 +BUT142 = 143 +BUT143 = 144 +BUT144 = 145 +BUT145 = 146 +BUT146 = 147 +BUT147 = 148 +BUT148 = 149 +BUT149 = 150 +BUT150 = 151 +BUT151 = 152 +BUT152 = 153 +BUT153 = 154 +BUT154 = 155 +BUT155 = 156 +BUT156 = 157 +BUT157 = 158 +BUT158 = 159 +BUT159 = 160 +BUT160 = 161 +BUT161 = 162 +BUT162 = 163 +BUT163 = 164 +BUT164 = 165 +BUT165 = 166 +BUT166 = 167 +BUT167 = 168 +BUT168 = 169 +BUT181 = 182 +BUT182 = 183 +BUT183 = 184 +BUT184 = 185 +BUT185 = 186 +BUT186 = 187 +BUT187 = 188 +BUT188 = 189 +BUT189 = 190 +MOUSE1 = 101 +MOUSE2 = 102 +MOUSE3 = 103 +LEFTMOUSE = 103 +MIDDLEMOUSE = 102 +RIGHTMOUSE = 101 +LPENBUT = 104 +BPAD0 = 105 +BPAD1 = 106 +BPAD2 = 107 +BPAD3 = 108 +LPENVALID = 109 +SWBASE = 111 +SW0 = 111 +SW1 = 112 +SW2 = 113 +SW3 = 114 +SW4 = 115 +SW5 = 116 +SW6 = 117 +SW7 = 118 +SW8 = 119 +SW9 = 120 +SW10 = 121 +SW11 = 122 +SW12 = 123 +SW13 = 124 +SW14 = 125 +SW15 = 126 +SW16 = 127 +SW17 = 128 +SW18 = 129 +SW19 = 130 +SW20 = 131 +SW21 = 132 +SW22 = 133 +SW23 = 134 +SW24 = 135 +SW25 = 136 +SW26 = 137 +SW27 = 138 +SW28 = 139 +SW29 = 140 +SW30 = 141 +SW31 = 142 +SBBASE = 182 +SBPICK = 182 +SBBUT1 = 183 +SBBUT2 = 184 +SBBUT3 = 185 +SBBUT4 = 186 +SBBUT5 = 187 +SBBUT6 = 188 +SBBUT7 = 189 +SBBUT8 = 190 +AKEY = 11 +BKEY = 36 +CKEY = 28 +DKEY = 18 +EKEY = 17 +FKEY = 19 +GKEY = 26 +HKEY = 27 +IKEY = 40 +JKEY = 34 +KKEY = 35 +LKEY = 42 +MKEY = 44 +NKEY = 37 +OKEY = 41 +PKEY = 48 +QKEY = 10 +RKEY = 24 +SKEY = 12 +TKEY = 25 +UKEY = 33 +VKEY = 29 +WKEY = 16 +XKEY = 21 +YKEY = 32 +ZKEY = 20 +ZEROKEY = 46 +ONEKEY = 8 +TWOKEY = 14 +THREEKEY = 15 +FOURKEY = 22 +FIVEKEY = 23 +SIXKEY = 30 +SEVENKEY = 31 +EIGHTKEY = 38 +NINEKEY = 39 +BREAKKEY = 1 +SETUPKEY = 2 +CTRLKEY = 3 +LEFTCTRLKEY = CTRLKEY +CAPSLOCKKEY = 4 +RIGHTSHIFTKEY = 5 +LEFTSHIFTKEY = 6 +NOSCRLKEY = 13 +ESCKEY = 7 +TABKEY = 9 +RETKEY = 51 +SPACEKEY = 83 +LINEFEEDKEY = 60 +BACKSPACEKEY = 61 +DELKEY = 62 +SEMICOLONKEY = 43 +PERIODKEY = 52 +COMMAKEY = 45 +QUOTEKEY = 50 +ACCENTGRAVEKEY = 55 +MINUSKEY = 47 +VIRGULEKEY = 53 +BACKSLASHKEY = 57 +EQUALKEY = 54 +LEFTBRACKETKEY = 49 +RIGHTBRACKETKEY = 56 +LEFTARROWKEY = 73 +DOWNARROWKEY = 74 +RIGHTARROWKEY = 80 +UPARROWKEY = 81 +PAD0 = 59 +PAD1 = 58 +PAD2 = 64 +PAD3 = 65 +PAD4 = 63 +PAD5 = 69 +PAD6 = 70 +PAD7 = 67 +PAD8 = 68 +PAD9 = 75 +PADPF1 = 72 +PADPF2 = 71 +PADPF3 = 79 +PADPF4 = 78 +PADPERIOD = 66 +PADMINUS = 76 +PADCOMMA = 77 +PADENTER = 82 +LEFTALTKEY = 143 +RIGHTALTKEY = 144 +RIGHTCTRLKEY = 145 +F1KEY = 146 +F2KEY = 147 +F3KEY = 148 +F4KEY = 149 +F5KEY = 150 +F6KEY = 151 +F7KEY = 152 +F8KEY = 153 +F9KEY = 154 +F10KEY = 155 +F11KEY = 156 +F12KEY = 157 +PRINTSCREENKEY = 158 +SCROLLLOCKKEY = 159 +PAUSEKEY = 160 +INSERTKEY = 161 +HOMEKEY = 162 +PAGEUPKEY = 163 +ENDKEY = 164 +PAGEDOWNKEY = 165 +NUMLOCKKEY = 166 +PADVIRGULEKEY = 167 +PADASTERKEY = 168 +PADPLUSKEY = 169 +SGIRESERVED = 256 +DIAL0 = 257 +DIAL1 = 258 +DIAL2 = 259 +DIAL3 = 260 +DIAL4 = 261 +DIAL5 = 262 +DIAL6 = 263 +DIAL7 = 264 +DIAL8 = 265 +MOUSEX = 266 +MOUSEY = 267 +LPENX = 268 +LPENY = 269 +BPADX = 270 +BPADY = 271 +CURSORX = 272 +CURSORY = 273 +GHOSTX = 274 +GHOSTY = 275 +SBTX = 276 +SBTY = 277 +SBTZ = 278 +SBRX = 279 +SBRY = 280 +SBRZ = 281 +SBPERIOD = 282 +TIMER0 = 515 +TIMER1 = 516 +TIMER2 = 517 +TIMER3 = 518 +KEYBD = 513 +RAWKEYBD = 514 +VALMARK = 523 +GERROR = 524 +REDRAW = 528 +WMSEND = 529 +WMREPLY = 530 +WMGFCLOSE = 531 +WMTXCLOSE = 532 +MODECHANGE = 533 +INPUTCHANGE = 534 +QFULL = 535 +PIECECHANGE = 536 +WINCLOSE = 537 +QREADERROR = 538 +WINFREEZE = 539 +WINTHAW = 540 +REDRAWICONIC = 541 +WINQUIT = 542 +DEPTHCHANGE = 543 +KEYBDFNAMES = 544 +KEYBDFSTRINGS = 545 +WINSHUT = 546 +INPUT0 = 1024 +INPUT1 = 1025 +INPUT2 = 1026 +INPUT3 = 1027 +INPUT4 = 1028 +INPUT5 = 1029 +INPUT6 = 1030 +INPUT7 = 1032 +OUTPUT0 = 1033 +OUTPUT1 = 1034 +OUTPUT2 = 1035 +OUTPUT3 = 1036 +OUTPUT4 = 1037 +OUTPUT5 = 1038 +OUTPUT6 = 1039 +OUTPUT7 = 1040 +MAXSGIDEVICE = 20000 +MENUBUTTON = RIGHTMOUSE diff --git a/Lib/irix5/GL.py b/Lib/irix5/GL.py new file mode 100755 index 00000000000..35487a74fab --- /dev/null +++ b/Lib/irix5/GL.py @@ -0,0 +1,365 @@ +# Constants defined in + +#************************************************************************** +#* * +#* Copyright (C) 1984, Silicon Graphics, Inc. * +#* * +#* These coded instructions, statements, and computer programs contain * +#* unpublished proprietary information of Silicon Graphics, Inc., and * +#* are protected by Federal copyright law. They may not be disclosed * +#* to third parties or copied or duplicated in any form, in whole or * +#* in part, without the prior written consent of Silicon Graphics, Inc. * +#* * +#************************************************************************** + +# Graphics Libary constants + +# Booleans +TRUE = 1 +FALSE = 0 + +# maximum X and Y screen coordinates +XMAXSCREEN = 1279 +YMAXSCREEN = 1023 +XMAXMEDIUM = 1023 # max for medium res monitor +YMAXMEDIUM = 767 +XMAX170 = 645 # max for RS-170 +YMAX170 = 484 +XMAXPAL = 779 # max for PAL +YMAXPAL = 574 + +# various hardware/software limits +ATTRIBSTACKDEPTH = 10 +VPSTACKDEPTH = 8 +MATRIXSTACKDEPTH = 32 +NAMESTACKDEPTH = 1025 +STARTTAG = -2 +ENDTAG = -3 +CPOSX_INVALID = -(2*XMAXSCREEN) + +# names for colors in color map loaded by greset +BLACK = 0 +RED = 1 +GREEN = 2 +YELLOW = 3 +BLUE = 4 +MAGENTA = 5 +CYAN = 6 +WHITE = 7 + +# popup colors +PUP_CLEAR = 0 +PUP_COLOR = 1 +PUP_BLACK = 2 +PUP_WHITE = 3 + +# defines for drawmode +NORMALDRAW = 0 +PUPDRAW = 1 +OVERDRAW = 2 +UNDERDRAW = 3 +CURSORDRAW = 4 + +# defines for defpattern +PATTERN_16 = 16 +PATTERN_32 = 32 +PATTERN_64 = 64 + +PATTERN_16_SIZE = 16 +PATTERN_32_SIZE = 64 +PATTERN_64_SIZE = 256 + +# defines for readsource +SRC_AUTO = 0 +SRC_FRONT = 1 +SRC_BACK = 2 +SRC_ZBUFFER = 3 +SRC_PUP = 4 +SRC_OVER = 5 +SRC_UNDER = 6 +SRC_FRAMEGRABBER = 7 + +# defines for blendfunction +BF_ZERO = 0 +BF_ONE = 1 +BF_DC = 2 +BF_SC = 2 +BF_MDC = 3 +BF_MSC = 3 +BF_SA = 4 +BF_MSA = 5 +BF_DA = 6 +BF_MDA = 7 + +# defines for zfunction +ZF_NEVER = 0 +ZF_LESS = 1 +ZF_EQUAL = 2 +ZF_LEQUAL = 3 +ZF_GREATER = 4 +ZF_NOTEQUAL = 5 +ZF_GEQUAL = 6 +ZF_ALWAYS = 7 + +# defines for zsource +ZSRC_DEPTH = 0 +ZSRC_COLOR = 1 + +# defines for pntsmooth +SMP_OFF = 0 +SMP_ON = 1 + +# defines for linesmooth +SML_OFF = 0 +SML_ON = 1 + +# defines for setpup +PUP_NONE = 0 +PUP_GREY = 1 + +# defines for glcompat +GLC_OLDPOLYGON = 0 +GLC_ZRANGEMAP = 1 + +# defines for curstype +C16X1 = 0 +C16X2 = 1 +C32X1 = 2 +C32X2 = 3 +CCROSS = 4 + +# defines for shademodel +FLAT = 0 +GOURAUD = 1 + +# defines for logicop +### LO_ZERO = 0x0 +### LO_AND = 0x1 +### LO_ANDR = 0x2 +### LO_SRC = 0x3 +### LO_ANDI = 0x4 +### LO_DST = 0x5 +### LO_XOR = 0x6 +### LO_OR = 0x7 +### LO_NOR = 0x8 +### LO_XNOR = 0x9 +### LO_NDST = 0xa +### LO_ORR = 0xb +### LO_NSRC = 0xc +### LO_ORI = 0xd +### LO_NAND = 0xe +### LO_ONE = 0xf + + +# +# START defines for getgdesc +# + +GD_XPMAX = 0 +GD_YPMAX = 1 +GD_XMMAX = 2 +GD_YMMAX = 3 +GD_ZMIN = 4 +GD_ZMAX = 5 +GD_BITS_NORM_SNG_RED = 6 +GD_BITS_NORM_SNG_GREEN = 7 +GD_BITS_NORM_SNG_BLUE = 8 +GD_BITS_NORM_DBL_RED = 9 +GD_BITS_NORM_DBL_GREEN = 10 +GD_BITS_NORM_DBL_BLUE = 11 +GD_BITS_NORM_SNG_CMODE = 12 +GD_BITS_NORM_DBL_CMODE = 13 +GD_BITS_NORM_SNG_MMAP = 14 +GD_BITS_NORM_DBL_MMAP = 15 +GD_BITS_NORM_ZBUFFER = 16 +GD_BITS_OVER_SNG_CMODE = 17 +GD_BITS_UNDR_SNG_CMODE = 18 +GD_BITS_PUP_SNG_CMODE = 19 +GD_BITS_NORM_SNG_ALPHA = 21 +GD_BITS_NORM_DBL_ALPHA = 22 +GD_BITS_CURSOR = 23 +GD_OVERUNDER_SHARED = 24 +GD_BLEND = 25 +GD_CIFRACT = 26 +GD_CROSSHAIR_CINDEX = 27 +GD_DITHER = 28 +GD_LINESMOOTH_CMODE = 30 +GD_LINESMOOTH_RGB = 31 +GD_LOGICOP = 33 +GD_NSCRNS = 35 +GD_NURBS_ORDER = 36 +GD_NBLINKS = 37 +GD_NVERTEX_POLY = 39 +GD_PATSIZE_64 = 40 +GD_PNTSMOOTH_CMODE = 41 +GD_PNTSMOOTH_RGB = 42 +GD_PUP_TO_OVERUNDER = 43 +GD_READSOURCE = 44 +GD_READSOURCE_ZBUFFER = 48 +GD_STEREO = 50 +GD_SUBPIXEL_LINE = 51 +GD_SUBPIXEL_PNT = 52 +GD_SUBPIXEL_POLY = 53 +GD_TRIMCURVE_ORDER = 54 +GD_WSYS = 55 +GD_ZDRAW_GEOM = 57 +GD_ZDRAW_PIXELS = 58 +GD_SCRNTYPE = 61 +GD_TEXTPORT = 62 +GD_NMMAPS = 63 +GD_FRAMEGRABBER = 64 +GD_TIMERHZ = 66 +GD_DBBOX = 67 +GD_AFUNCTION = 68 +GD_ALPHA_OVERUNDER = 69 +GD_BITS_ACBUF = 70 +GD_BITS_ACBUF_HW = 71 +GD_BITS_STENCIL = 72 +GD_CLIPPLANES = 73 +GD_FOGVERTEX = 74 +GD_LIGHTING_TWOSIDE = 76 +GD_POLYMODE = 77 +GD_POLYSMOOTH = 78 +GD_SCRBOX = 79 +GD_TEXTURE = 80 + +# return value for inquiries when there is no limit +GD_NOLIMIT = 2 + +# return values for GD_WSYS +GD_WSYS_NONE = 0 +GD_WSYS_4S = 1 + +# return values for GD_SCRNTYPE +GD_SCRNTYPE_WM = 0 +GD_SCRNTYPE_NOWM = 1 + +# +# END defines for getgdesc +# + + +# +# START NURBS interface definitions +# + +# NURBS Rendering Properties +N_PIXEL_TOLERANCE = 1 +N_CULLING = 2 +N_DISPLAY = 3 +N_ERRORCHECKING = 4 +N_SUBDIVISIONS = 5 +N_S_STEPS = 6 +N_T_STEPS = 7 +N_TILES = 8 + +N_SHADED = 1.0 + +# --------------------------------------------------------------------------- +# FLAGS FOR NURBS SURFACES AND CURVES +# +# Bit: 9876 5432 1 0 +# |tttt|nnnn|f|r| : r - 1 bit = 1 if rational coordinate exists +# : f - 1 bit = 1 if rational coordinate is before rest +# : = 0 if rational coordinate is after rest +# : nnnn - 4 bits for number of coordinates +# : tttt - 4 bits for type of data (color, position, etc.) +# +# NURBS data type +# N_T_ST 0 parametric space data +# N_T_XYZ 1 model space data +# +# rational or non-rational data and position in memory +# N_NONRATIONAL 0 non-rational data +# N_RATAFTER 1 rational data with rat coord after rest +# N_RATBEFORE 3 rational data with rat coord before rest +# +# N_MKFLAG(a,b,c) ((a<<6) | (b<<2) | c) +# +# --------------------------------------------------------------------------- +# +N_ST = 0x8 # N_MKFLAG( N_T_ST, 2, N_NONRATIONAL ) +N_STW = 0xd # N_MKFLAG( N_T_ST, 3, N_RATAFTER ) +N_WST = 0xf # N_MKFLAG( N_T_ST, 3, N_RATBEFORE ) +N_XYZ = 0x4c # N_MKFLAG( N_T_XYZ, 3, N_NONRATIONAL ) +N_XYZW = 0x51 # N_MKFLAG( N_T_XYZ, 4, N_RATAFTER ) +N_WXYZ = 0x53 # N_MKFLAG( N_T_XYZ, 4, N_RATBEFORE ) + +# +# END NURBS interface definitions +# + + +# +# START lighting model defines +# + +LMNULL = 0.0 + +# MATRIX modes +MSINGLE = 0 +MPROJECTION = 1 +MVIEWING = 2 + +# LIGHT constants +MAXLIGHTS = 8 +MAXRESTRICTIONS = 4 + +# MATERIAL properties +DEFMATERIAL = 0 +EMISSION = 1 +AMBIENT = 2 +DIFFUSE = 3 +SPECULAR = 4 +SHININESS = 5 +COLORINDEXES = 6 +ALPHA = 7 + +# LIGHT properties +DEFLIGHT = 100 +LCOLOR = 101 +POSITION = 102 + +# LIGHTINGMODEL properties +DEFLMODEL = 200 +LOCALVIEWER = 201 +ATTENUATION = 202 + +# TARGET constants +MATERIAL = 1000 +LIGHT0 = 1100 +LIGHT1 = 1101 +LIGHT2 = 1102 +LIGHT3 = 1103 +LIGHT4 = 1104 +LIGHT5 = 1105 +LIGHT6 = 1106 +LIGHT7 = 1107 +LMODEL = 1200 + +# lmcolor modes +LMC_COLOR = 0 +LMC_EMISSION = 1 +LMC_AMBIENT = 2 +LMC_DIFFUSE = 3 +LMC_SPECULAR = 4 +LMC_AD = 5 +LMC_NULL = 6 + +# +# END lighting model defines +# + + +# +# START distributed graphics library defines +# + +DGLSINK = 0 # sink connection +DGLLOCAL = 1 # local connection +DGLTSOCKET = 2 # tcp socket connection +DGL4DDN = 3 # 4DDN (DECnet) + +# +# END distributed graphics library defines +# diff --git a/Lib/irix5/auds.py b/Lib/irix5/auds.py new file mode 100755 index 00000000000..549c0a7a346 --- /dev/null +++ b/Lib/irix5/auds.py @@ -0,0 +1,106 @@ +import audio + +RATE = 8192 + +# Initialize the audio stuff +audio.setrate(3) +audio.setoutgain(100) # for speaker + +play = audio.write + +def samp(n): + savegain = audio.getoutgain() + try: + audio.setoutgain(0) + x = raw_input('Hit Enter to sample ' + `n` + ' seconds: ') + return audio.read(n*RATE) + finally: + audio.setoutgain(savegain) + +def echo(s, delay, gain): + return s[:delay] + audio.add(s[delay:], audio.amplify(s, gain, gain)) + +def save(s, file): + f = open(file, 'w') + f.write(s) + +def load(file): + return loadfp(open(file, 'r')) + +def loadfp(fp): + s = '' + while 1: + buf = fp.read(16*1024) + if not buf: break + s = s + buf + return s + +def unbias(s): + if not s: return s + a = audio.chr2num(s) + sum = 0 + for i in a: sum = sum + i + bias = (sum + len(a)/2) / len(a) + print 'Bias value:', bias + if bias: + for i in range(len(a)): + a[i] = a[i] - bias + s = audio.num2chr(a) + return s + +# Stretch by a/b. +# Think of this as converting the sampling rate from a samples/sec +# to b samples/sec. Or, if the input is a bytes long, the output +# will be b bytes long. +# +def stretch(s, a, b): + y = audio.chr2num(s) + m = len(y) + out = [] + n = m * b / a + # i, j will walk through y and out (step 1) + # ib, ja are i*b, j*a and are kept as close together as possible + i, ib = 0, 0 + j, ja = 0, 0 + for j in range(n): + ja = ja+a + while ib < ja: + i = i+1 + ib = ib+b + if i >= m: + break + if ib = ja: + out.append(y[i]) + else: + out.append((y[i]*(ja-(ib-b)) + y[i-1]*(ib-ja)) / b) + return audio.num2chr(out) + +def sinus(freq): # return a 1-second sine wave + from math import sin, pi + factor = 2.0*pi*float(freq)/float(RATE) + list = range(RATE) + for i in list: + list[i] = int(sin(float(i) * factor) * 127.0) + return audio.num2chr(list) + +def softclip(s): + if '\177' not in s and '\200' not in s: + return s + num = audio.chr2num(s) + extremes = (-128, 127) + for i in range(1, len(num)-1): + if num[i] in extremes: + num[i] = (num[i-1] + num[i+1]) / 2 + return audio.num2chr(num) + +def demo(): + gday = load('gday')[1000:6000] + save(gday, 'gday0') + gg = [gday] + for i in range(1, 10): + for g in gg: play(g) + g = stretch(gday, 10, 10-i) + save(g, 'gday' + `i`) + gg.append(g) + while 1: + for g in gg: play(g) diff --git a/Lib/irix5/panel.py b/Lib/irix5/panel.py new file mode 100755 index 00000000000..eb115086f66 --- /dev/null +++ b/Lib/irix5/panel.py @@ -0,0 +1,281 @@ +# Module 'panel' +# +# Support for the Panel library. +# Uses built-in module 'pnl'. +# Applciations should use 'panel.function' instead of 'pnl.function'; +# most 'pnl' functions are transparently exported by 'panel', +# but dopanel() is overridden and you have to use this version +# if you want to use callbacks. + + +import pnl + + +debug = 0 + + +# Test if an object is a list. +# +def is_list(x): + return type(x) = type([]) + + +# Reverse a list. +# +def reverse(list): + res = [] + for item in list: + res.insert(0, item) + return res + + +# Get an attribute of a list, which may itself be another list. +# Don't use 'prop' for name. +# +def getattrlist(list, name): + for item in list: + if item and is_list(item) and item[0] = name: + return item[1:] + return [] + + +# Get a property of a list, which may itself be another list. +# +def getproplist(list, name): + for item in list: + if item and is_list(item) and item[0] = 'prop': + if len(item) > 1 and item[1] = name: + return item[2:] + return [] + + +# Test if an actuator description contains the property 'end-of-group' +# +def is_endgroup(list): + x = getproplist(list, 'end-of-group') + return (x and x[0] = '#t') + + +# Neatly display an actuator definition given as S-expression +# the prefix string is printed before each line. +# +def show_actuator(prefix, a): + for item in a: + if not is_list(item): + print prefix, item + elif item and item[0] = 'al': + print prefix, 'Subactuator list:' + for a in item[1:]: + show_actuator(prefix + ' ', a) + elif len(item) = 2: + print prefix, item[0], '=>', item[1] + elif len(item) = 3 and item[0] = 'prop': + print prefix, 'Prop', item[1], '=>', + print item[2] + else: + print prefix, '?', item + + +# Neatly display a panel. +# +def show_panel(prefix, p): + for item in p: + if not is_list(item): + print prefix, item + elif item and item[0] = 'al': + print prefix, 'Actuator list:' + for a in item[1:]: + show_actuator(prefix + ' ', a) + elif len(item) = 2: + print prefix, item[0], '=>', item[1] + elif len(item) = 3 and item[0] = 'prop': + print prefix, 'Prop', item[1], '=>', + print item[2] + else: + print prefix, '?', item + + +# Exception raised by build_actuator or build_panel. +# +panel_error = 'panel error' + + +# Dummy callback used to initialize the callbacks. +# +def dummy_callback(arg): + pass + + +# Assign attributes to members of the target. +# Attribute names in exclist are ignored. +# The member name is the attribute name prefixed with the prefix. +# +def assign_members(target, attrlist, exclist, prefix): + for item in attrlist: + if is_list(item) and len(item) = 2 and item[0] not in exclist: + name, value = item[0], item[1] + ok = 1 + if value[0] in '-0123456789': + value = eval(value) + elif value[0] = '"': + value = value[1:-1] + elif value = 'move-then-resize': + # Strange default set by Panel Editor... + ok = 0 + else: + print 'unknown value', value, 'for', name + ok = 0 + if ok: + lhs = 'target.' + prefix + name + stmt = lhs + '=' + `value` + if debug: print 'exec', stmt + try: + exec(stmt + '\n') + except KeyboardInterrupt: # Don't catch this! + raise KeyboardInterrupt + except: + print 'assign failed:', stmt + + +# Build a real actuator from an actuator descriptior. +# Return a pair (actuator, name). +# +def build_actuator(descr): + namelist = getattrlist(descr, 'name') + if namelist: + # Assume it is a string + actuatorname = namelist[0][1:-1] + else: + actuatorname = '' + type = descr[0] + if type[:4] = 'pnl_': type = type[4:] + act = pnl.mkact(type) + act.downfunc = act.activefunc = act.upfunc = dummy_callback + # + assign_members(act, descr[1:], ('al', 'data', 'name'), '') + # + # Treat actuator-specific data + # + datalist = getattrlist(descr, 'data') + prefix = '' + if type[-4:] = 'puck': + prefix = 'puck_' + elif type = 'mouse': + prefix = 'mouse_' + assign_members(act, datalist, (), prefix) + # + return act, actuatorname + + +# Build all sub-actuators and add them to the super-actuator. +# The super-actuator must already have been added to the panel. +# Sub-actuators with defined names are added as members to the panel +# so they can be referenced as p.name. +# +# Note: I have no idea how panel.endgroup() works when applied +# to a sub-actuator. +# +def build_subactuators(panel, super_act, al): + # + # This is nearly the same loop as below in build_panel(), + # except a call is made to addsubact() instead of addact(). + # + for a in al: + act, name = build_actuator(a) + act.addsubact(super_act) + if name: + stmt = 'panel.' + name + ' = act' + if debug: print 'exec', stmt + exec(stmt + '\n') + if is_endgroup(a): + panel.endgroup() + sub_al = getattrlist(a, 'al') + if sub_al: + build_subactuators(panel, act, sub_al) + # + # Fix the actuator to which whe just added subactuators. + # This can't hurt (I hope) and is needed for the scroll actuator. + # + super_act.fixact() + + +# Build a real panel from a panel definition. +# Return a panel object p, where for each named actuator a, p.name is a +# reference to a. +# +def build_panel(descr): + # + # Sanity check + # + if (not descr) or descr[0] <> 'panel': + raise panel_error, 'panel description must start with "panel"' + # + if debug: show_panel('', descr) + # + # Create an empty panel + # + panel = pnl.mkpanel() + # + # Assign panel attributes + # + assign_members(panel, descr[1:], ('al'), '') + # + # Look for actuator list + # + al = getattrlist(descr, 'al') + # + # The order in which actuators are created is important + # because of the endgroup() operator. + # Unfortunately the Panel Editor outputs the actuator list + # in reverse order, so we reverse it here. + # + al = reverse(al) + # + for a in al: + act, name = build_actuator(a) + act.addact(panel) + if name: + stmt = 'panel.' + name + ' = act' + exec(stmt + '\n') + if is_endgroup(a): + panel.endgroup() + sub_al = getattrlist(a, 'al') + if sub_al: + build_subactuators(panel, act, sub_al) + # + return panel + + +# Wrapper around pnl.dopanel() which calls call-back functions. +# +def my_dopanel(): + # Extract only the first 4 elements to allow for future expansion + a, down, active, up = pnl.dopanel()[:4] + if down: + down.downfunc(down) + if active: + active.activefunc(active) + if up: + up.upfunc(up) + return a + + +# Create one or more panels from a description file (S-expressions) +# generated by the Panel Editor. +# +def defpanellist(file): + import parser + descrlist = parser.parse_file(open(file, 'r')) + panellist = [] + for descr in descrlist: + panellist.append(build_panel(descr)) + return panellist + + +# Import everything from built-in method pnl, so the user can always +# use panel.foo() instead of pnl.foo(). +# This gives *no* performance penalty once this module is imported. +# +from pnl import * # for export + +dopanel = my_dopanel # override pnl.dopanel diff --git a/Lib/irix5/panelparser.py b/Lib/irix5/panelparser.py new file mode 100755 index 00000000000..9c9ee022750 --- /dev/null +++ b/Lib/irix5/panelparser.py @@ -0,0 +1,128 @@ +# Module 'parser' +# +# Parse S-expressions output by the Panel Editor +# (which is written in Scheme so it can't help writing S-expressions). +# +# See notes at end of file. + + +whitespace = ' \t\n' +operators = '()\'' +separators = operators + whitespace + ';' + '"' + + +# Tokenize a string. +# Return a list of tokens (strings). +# +def tokenize_string(s): + tokens = [] + while s: + c = s[:1] + if c in whitespace: + s = s[1:] + elif c = ';': + s = '' + elif c = '"': + n = len(s) + i = 1 + while i < n: + c = s[i] + i = i+1 + if c = '"': break + if c = '\\': i = i+1 + tokens.append(s[:i]) + s = s[i:] + elif c in operators: + tokens.append(c) + s = s[1:] + else: + n = len(s) + i = 1 + while i < n: + if s[i] in separators: break + i = i+1 + tokens.append(s[:i]) + s = s[i:] + return tokens + + +# Tokenize a whole file (given as file object, not as file name). +# Return a list of tokens (strings). +# +def tokenize_file(fp): + tokens = [] + while 1: + line = fp.readline() + if not line: break + tokens = tokens + tokenize_string(line) + return tokens + + +# Exception raised by parse_exr. +# +syntax_error = 'syntax error' + + +# Parse an S-expression. +# Input is a list of tokens as returned by tokenize_*(). +# Return a pair (expr, tokens) +# where expr is a list representing the s-expression, +# and tokens contains the remaining tokens. +# May raise syntax_error. +# +def parse_expr(tokens): + if (not tokens) or tokens[0] <> '(': + raise syntax_error, 'expected "("' + tokens = tokens[1:] + expr = [] + while 1: + if not tokens: + raise syntax_error, 'missing ")"' + if tokens[0] = ')': + return expr, tokens[1:] + elif tokens[0] = '(': + subexpr, tokens = parse_expr(tokens) + expr.append(subexpr) + else: + expr.append(tokens[0]) + tokens = tokens[1:] + + +# Parse a file (given as file object, not as file name). +# Return a list of parsed S-expressions found at the top level. +# +def parse_file(fp): + tokens = tokenize_file(fp) + exprlist = [] + while tokens: + expr, tokens = parse_expr(tokens) + exprlist.append(expr) + return exprlist + + +# EXAMPLE: +# +# The input +# '(hip (hop hur-ray))' +# +# passed to tokenize_string() returns the token list +# ['(', 'hip', '(', 'hop', 'hur-ray', ')', ')'] +# +# When this is passed to parse_expr() it returns the expression +# ['hip', ['hop', 'hur-ray']] +# plus an empty token list (because there are no tokens left. +# +# When a file containing the example is passed to parse_file() it returns +# a list whose only element is the output of parse_expr() above: +# [['hip', ['hop', 'hur-ray']]] + + +# TOKENIZING: +# +# Comments start with semicolon (;) and continue till the end of the line. +# +# Tokens are separated by whitespace, except the following characters +# always form a separate token (outside strings): +# ( ) ' +# Strings are enclosed in double quotes (") and backslash (\) is used +# as escape character in strings. diff --git a/Lib/lib-old/dump.py b/Lib/lib-old/dump.py new file mode 100644 index 00000000000..cecc275f75b --- /dev/null +++ b/Lib/lib-old/dump.py @@ -0,0 +1,63 @@ +# Module 'dump' +# +# Print python code that reconstructs a variable. +# This only works in certain cases. +# +# It works fine for: +# - ints and floats (except NaNs and other weird things) +# - strings +# - compounds and lists, provided it works for all their elements +# - imported modules, provided their name is the module name +# +# It works for top-level dictionaries but not for dictionaries +# contained in other objects (could be made to work with some hassle +# though). +# +# It does not work for functions (all sorts), classes, class objects, +# windows, files etc. +# +# Finally, objects referenced by more than one name or contained in more +# than one other object lose their sharing property (this is bad for +# strings used as exception identifiers, for instance). + +# Dump a whole symbol table +# +def dumpsymtab(dict): + for key in dict.keys(): + dumpvar(key, dict[key]) + +# Dump a single variable +# +def dumpvar(name, x): + import sys + t = type(x) + if t = type({}): + print name, '= {}' + for key in x.keys(): + item = x[key] + if not printable(item): + print '#', + print name, '[', `key`, '] =', `item` + elif t in (type(''), type(0), type(0.0), type([]), type(())): + if not printable(x): + print '#', + print name, '=', `x` + elif t = type(sys): + print 'import', name, '#', x + else: + print '#', name, '=', x + +# check if a value is printable in a way that can be read back with input() +# +def printable(x): + t = type(x) + if t in (type(''), type(0), type(0.0)): + return 1 + if t in (type([]), type(())): + for item in x: + if not printable(item): + return 0 + return 1 + if x = {}: + return 1 + return 0 diff --git a/Lib/lib-old/rand.py b/Lib/lib-old/rand.py new file mode 100644 index 00000000000..06164833284 --- /dev/null +++ b/Lib/lib-old/rand.py @@ -0,0 +1,12 @@ +# Module 'rand' + +import whrandom + +def srand(seed): + whrandom.seed(seed%256, seed/256%256, seed/65536%256) + +def rand(): + return int(whrandom.random() * 32768.0) % 32768 + +def choice(seq): + return seq[rand() % len(seq)] diff --git a/Lib/lib-old/util.py b/Lib/lib-old/util.py new file mode 100644 index 00000000000..dc67686a327 --- /dev/null +++ b/Lib/lib-old/util.py @@ -0,0 +1,9 @@ +# Module 'util' -- some useful functions that dont fit elsewhere + +# Remove an item from a list at most once +# +def remove(item, list): + for i in range(len(list)): + if list[i] = item: + del list[i] + break diff --git a/Lib/lib-stdwin/anywin.py b/Lib/lib-stdwin/anywin.py new file mode 100644 index 00000000000..bb7e86547b8 --- /dev/null +++ b/Lib/lib-stdwin/anywin.py @@ -0,0 +1,14 @@ +# Module 'anywin' +# Open a file or directory in a window + +import dirwin +import filewin +import path + +def open(name): + print 'opening', name, '...' + if path.isdir(name): + w = dirwin.open(name) + else: + w = filewin.open(name) + return w diff --git a/Lib/lib-stdwin/dirwin.py b/Lib/lib-stdwin/dirwin.py new file mode 100644 index 00000000000..5df85e7e39f --- /dev/null +++ b/Lib/lib-stdwin/dirwin.py @@ -0,0 +1,28 @@ +# Module 'dirwin' + +# Directory windows, a subclass of listwin + +import gwin +import listwin +import anywin +import path +import dircache + +def action(w, string, i, detail): + (h, v), clicks, button, mask = detail + if clicks = 2: + name = path.cat(w.name, string) + try: + w = anywin.open(name) + except posix.error, why: + stdwin.message('Can\'t open ' + name + ': ' + why[1]) + +def open(name): + name = path.cat(name, '') + list = dircache.opendir(name)[:] + list.sort() + dircache.annotate(name, list) + w = listwin.open(name, list) + w.name = name + w.action = action + return w diff --git a/Lib/lib-stdwin/filewin.py b/Lib/lib-stdwin/filewin.py new file mode 100644 index 00000000000..1beb0b6520c --- /dev/null +++ b/Lib/lib-stdwin/filewin.py @@ -0,0 +1,31 @@ +# Module 'filewin' +# File windows, a subclass of textwin (which is a subclass of gwin) + +import stdwin +import textwin +import path + +builtin_open = open + +def readfile(fn): # Return a string containing the file's contents + fp = builtin_open(fn, 'r') + a = '' + n = 8096 + while 1: + b = fp.read(n) + if not b: break + a = a + b + return a + + +# FILE WINDOW + +def open_readonly(fn): # Open a file window + w = textwin.open_readonly(fn, readfile(fn)) + w.fn = fn + return w + +def open(fn): # Open a file window + w = textwin.open(fn, readfile(fn)) + w.fn = fn + return w diff --git a/Lib/lib-stdwin/gwin.py b/Lib/lib-stdwin/gwin.py new file mode 100644 index 00000000000..15aa4327ce5 --- /dev/null +++ b/Lib/lib-stdwin/gwin.py @@ -0,0 +1,118 @@ +# Module 'gwin' +# Generic stdwin windows + +# This is used as a base class from which to derive other window types. +# The mainloop() function here is an event dispatcher for all window types. + +import stdwin +import stdwinsupport + +S = stdwinsupport # Shorthand + +windows = [] # List of open windows + + +# Open a window + +def open(title): # Open a generic window + w = stdwin.open(title) + stdwin.setdefwinsize(0, 0) + # Set default event handlers + w.draw = nop + w.char = nop + w.mdown = nop + w.mmove = nop + w.mup = nop + w.m2down = m2down + w.m2up = m2up + w.size = nop + w.move = nop + w.activate = w.deactivate = nop + w.timer = nop + # default command handlers + w.close = close + w.tab = tab + w.enter = enter + w.backspace = backspace + w.arrow = arrow + w.kleft = w.kup = w.kright = w.kdown = nop + windows.append(w) + return w + + +# Generic event dispatching + +def mainloop(): # Handle events until no windows left + while windows: + treatevent(stdwin.getevent()) + +def treatevent(e): # Handle a stdwin event + type, w, detail = e + if type = S.we_draw: + w.draw(w, detail) + elif type = S.we_menu: + m, item = detail + m.action[item](w, m, item) + elif type = S.we_command: + treatcommand(w, detail) + elif type = S.we_char: + w.char(w, detail) + elif type = S.we_mouse_down: + if detail[1] > 1: w.m2down(w, detail) + else: w.mdown(w, detail) + elif type = S.we_mouse_move: + w.mmove(w, detail) + elif type = S.we_mouse_up: + if detail[1] > 1: w.m2up(w, detail) + else: w.mup(w, detail) + elif type = S.we_size: + w.size(w, w.getwinsize()) + elif type = S.we_activate: + w.activate(w) + elif type = S.we_deactivate: + w.deactivate(w) + elif type = S.we_move: + w.move(w) + elif type = S.we_timer: + w.timer(w) + +def treatcommand(w, type): # Handle a we_command event + if type = S.wc_close: + w.close(w) + elif type = S.wc_return: + w.enter(w) + elif type = S.wc_tab: + w.tab(w) + elif type = S.wc_backspace: + w.backspace(w) + elif type in (S.wc_left, S.wc_up, S.wc_right, S.wc_down): + w.arrow(w, type) + + +# Methods + +def close(w): # Close method + for i in range(len(windows)): + if windows[i] is w: + del windows[i] + break + +def arrow(w, detail): # Arrow key method + if detail = S.wc_left: + w.kleft(w) + elif detail = S.wc_up: + w.kup(w) + elif detail = S.wc_right: + w.kright(w) + elif detail = S.wc_down: + w.kdown(w) + + +# Trivial methods + +def tab(w): w.char(w, '\t') +def enter(w): w.char(w, '\n') # 'return' is a Python reserved word +def backspace(w): w.char(w, '\b') +def m2down(w, detail): w.mdown(w, detail) +def m2up(w, detail): w.mup(w, detail) +def nop(args): pass diff --git a/Lib/lib-stdwin/listwin.py b/Lib/lib-stdwin/listwin.py new file mode 100644 index 00000000000..9480a81fc9c --- /dev/null +++ b/Lib/lib-stdwin/listwin.py @@ -0,0 +1,47 @@ +# Module 'listwin' +# List windows, a subclass of gwin + +import gwin +import stdwin + +def maxlinewidth(a): # Compute maximum textwidth of lines in a sequence + max = 0 + for line in a: + width = stdwin.textwidth(line) + if width > max: max = width + return max + +def action(w, string, i, detail): # Default item selection method + pass + +def mup(w, detail): # Mouse up method + (h, v), clicks, button, mask = detail + i = divmod(v, w.lineheight)[0] + if 0 <= i < len(w.data): + w.action(w, w.data[i], i, detail) + +def draw(w, ((left, top), (right, bottom))): # Text window draw method + data = w.data + d = w.begindrawing() + lh = w.lineheight + itop = top/lh + ibot = (bottom-1)/lh + 1 + if itop < 0: itop = 0 + if ibot > len(data): ibot = len(data) + for i in range(itop, ibot): d.text((0, i*lh), data[i]) + +def open(title, data): # Display a list of texts in a window + lineheight = stdwin.lineheight() + h, v = maxlinewidth(data), len(data)*lineheight + h0, v0 = h + stdwin.textwidth(' '), v + lineheight + if h0 > stdwin.textwidth(' ')*80: h0 = 0 + if v0 > stdwin.lineheight()*24: v0 = 0 + stdwin.setdefwinsize(h0, v0) + w = gwin.open(title) + w.setdocsize(h, v) + w.lineheight = lineheight + w.data = data + w.draw = draw + w.action = action + w.mup = mup + return w diff --git a/Lib/lib-stdwin/rect.py b/Lib/lib-stdwin/rect.py new file mode 100644 index 00000000000..c044b9f0c71 --- /dev/null +++ b/Lib/lib-stdwin/rect.py @@ -0,0 +1,87 @@ +# Module 'rect'. +# +# Operations on rectangles. +# There is some normalization: all results return the object 'empty' +# if their result would contain no points. + + +# Exception. +# +error = 'rect.error' + + +# The empty rectangle. +# +empty = (0, 0), (0, 0) + + +# Check if a rectangle is empty. +# +def is_empty((left, top), (right, bottom)): + return left >= right or top >= bottom + + +# Compute the intersection or two or more rectangles. +# This works with a list or tuple argument. +# +def intersect(list): + if not list: raise error, 'intersect called with empty list' + if is_empty(list[0]): return empty + (left, top), (right, bottom) = list[0] + for rect in list[1:]: + if not is_empty(rect): + (l, t), (r, b) = rect + if left < l: left = l + if top < t: top = t + if right > r: right = r + if bottom > b: bottom = b + if is_empty((left, top), (right, bottom)): + return empty + return (left, top), (right, bottom) + + +# Compute the smallest rectangle containing all given rectangles. +# This works with a list or tuple argument. +# +def union(list): + (left, top), (right, bottom) = empty + for (l, t), (r, b) in list[1:]: + if not is_empty((l, t), (r, b)): + if l < left: left = l + if t < top: top = t + if r > right: right = r + if b > bottom: bottom = b + res = (left, top), (right, bottom) + if is_empty(res): + return empty + return res + + +# Check if a point is in a rectangle. +# +def pointinrect((h, v), ((left, top), (right, bottom))): + return left <= h < right and top <= v < bottom + + +# Return a rectangle that is dh, dv inside another +# +def inset(((left, top), (right, bottom)), (dh, dv)): + left = left + dh + top = top + dv + right = right - dh + bottom = bottom - dv + r = (left, top), (right, bottom) + if is_empty(r): + return empty + else: + return r + + +# Conversions between rectangles and 'geometry tuples', +# given as origin (h, v) and dimensions (width, height). +# +def rect2geom((left, top), (right, bottom)): + return (left, top), (right-left, bottom-top) + +def geom2rect((h, v), (width, height)): + return (h, v), (h+width, v+height) diff --git a/Lib/lib-stdwin/stdwinevents.py b/Lib/lib-stdwin/stdwinevents.py new file mode 100644 index 00000000000..889dd959829 --- /dev/null +++ b/Lib/lib-stdwin/stdwinevents.py @@ -0,0 +1,36 @@ +# Module 'stdwinevents' -- Constants for stdwin event types +# +# Suggested usage: +# from stdwinevents import * + +# The function stdwin.getevent() returns a tuple containing: +# (type, window, detail) +# where detail may be or a value depending on type, see below: + +# Values for type: + +WE_NULL = 0 # not reported -- means 'no event' internally +WE_ACTIVATE = 1 # detail is +WE_CHAR = 2 # detail is the character +WE_COMMAND = 3 # detail is one of the WC_* constants below +WE_MOUSE_DOWN = 4 # detail is ((h, v), clicks, button, mask) +WE_MOUSE_MOVE = 5 # ditto +WE_MOUSE_UP = 6 # ditto +WE_MENU = 7 # detail is (menu, item) +WE_SIZE = 8 # detail is (width, height) [???] +WE_MOVE = 9 # not reported -- reserved for future use +WE_DRAW = 10 # detail is ((left, top), (right, bottom)) +WE_TIMER = 11 # detail is +WE_DEACTIVATE = 12 # detail is + +# Values for detail when type is WE_COMMAND: + +WC_CLOSE = 1 # user hit close box +WC_LEFT = 2 # left arrow key +WC_RIGHT = 3 # right arrow key +WC_UP = 4 # up arrow key +WC_DOWN = 5 # down arrow key +WC_CANCEL = 6 # not reported -- turned into KeyboardInterrupt +WC_BACKSPACE = 7 # backspace key +WC_TAB = 8 # tab key +WC_RETURN = 9 # return or enter key diff --git a/Lib/lib-stdwin/tablewin.py b/Lib/lib-stdwin/tablewin.py new file mode 100644 index 00000000000..05a954e5b86 --- /dev/null +++ b/Lib/lib-stdwin/tablewin.py @@ -0,0 +1,237 @@ +# Module 'tablewin' + +# Display a table, with per-item actions: + +# A1 | A2 | A3 | .... | AN +# B1 | B2 | B3 | .... | BN +# C1 | C2 | C3 | .... | CN +# .. | .. | .. | .... | .. +# Z1 | Z2 | Z3 | .... | ZN + +# Not all columns need to have the same length. +# The data structure is a list of columns; +# each column is a list of items. +# Each item is a pair of a string and an action procedure. +# The first item may be a column title. + +import stdwin +import gwin + +def open(title, data): # Public function to open a table window + # + # Set geometry parameters (one day, these may be changeable) + # + margin = stdwin.textwidth(' ') + lineheight = stdwin.lineheight() + # + # Geometry calculations + # + colstarts = [0] + totwidth = 0 + maxrows = 0 + for coldata in data: + # Height calculations + rows = len(coldata) + if rows > maxrows: maxrows = rows + # Width calculations + width = colwidth(coldata) + margin + totwidth = totwidth + width + colstarts.append(totwidth) + # + # Calculate document and window height + # + docwidth, docheight = totwidth, maxrows*lineheight + winwidth, winheight = docwidth, docheight + if winwidth > stdwin.textwidth('n')*100: winwidth = 0 + if winheight > stdwin.lineheight()*30: winheight = 0 + # + # Create the window + # + stdwin.setdefwinsize(winwidth, winheight) + w = gwin.open(title) + # + # Set properties and override methods + # + w.data = data + w.margin = margin + w.lineheight = lineheight + w.colstarts = colstarts + w.totwidth = totwidth + w.maxrows = maxrows + w.selection = (-1, -1) + w.lastselection = (-1, -1) + w.selshown = 0 + w.setdocsize(docwidth, docheight) + w.draw = draw + w.mup = mup + w.arrow = arrow + # + # Return + # + return w + +def update(w, data): # Change the data + # + # Hide selection + # + hidesel(w, w.begindrawing()) + # + # Get old geometry parameters + # + margin = w.margin + lineheight = w.lineheight + # + # Geometry calculations + # + colstarts = [0] + totwidth = 0 + maxrows = 0 + for coldata in data: + # Height calculations + rows = len(coldata) + if rows > maxrows: maxrows = rows + # Width calculations + width = colwidth(coldata) + margin + totwidth = totwidth + width + colstarts.append(totwidth) + # + # Calculate document and window height + # + docwidth, docheight = totwidth, maxrows*lineheight + # + # Set changed properties and change window size + # + w.data = data + w.colstarts = colstarts + w.totwidth = totwidth + w.maxrows = maxrows + w.change((0, 0), (10000, 10000)) + w.setdocsize(docwidth, docheight) + w.change((0, 0), (docwidth, docheight)) + # + # Show selection, or forget it if out of range + # + showsel(w, w.begindrawing()) + if not w.selshown: w.selection = (-1, -1) + +def colwidth(coldata): # Subroutine to calculate column width + maxwidth = 0 + for string, action in coldata: + width = stdwin.textwidth(string) + if width > maxwidth: maxwidth = width + return maxwidth + +def draw(w, ((left, top), (right, bottom))): # Draw method + ileft = whichcol(w, left) + iright = whichcol(w, right-1) + 1 + if iright > len(w.data): iright = len(w.data) + itop = divmod(top, w.lineheight)[0] + if itop < 0: itop = 0 + ibottom, remainder = divmod(bottom, w.lineheight) + if remainder: ibottom = ibottom + 1 + d = w.begindrawing() + if ileft <= w.selection[0] < iright: + if itop <= w.selection[1] < ibottom: + hidesel(w, d) + d.erase((left, top), (right, bottom)) + for i in range(ileft, iright): + col = w.data[i] + jbottom = len(col) + if ibottom < jbottom: jbottom = ibottom + h = w.colstarts[i] + v = itop * w.lineheight + for j in range(itop, jbottom): + string, action = col[j] + d.text((h, v), string) + v = v + w.lineheight + showsel(w, d) + +def mup(w, detail): # Mouse up method + (h, v), nclicks, button, mask = detail + icol = whichcol(w, h) + if 0 <= icol < len(w.data): + irow = divmod(v, w.lineheight)[0] + col = w.data[icol] + if 0 <= irow < len(col): + string, action = col[irow] + action(w, string, (icol, irow), detail) + +def whichcol(w, h): # Return column number (may be >= len(w.data)) + for icol in range(0, len(w.data)): + if h < w.colstarts[icol+1]: + return icol + return len(w.data) + +def arrow(w, type): + import stdwinsupport + S = stdwinsupport + if type = S.wc_left: + incr = -1, 0 + elif type = S.wc_up: + incr = 0, -1 + elif type = S.wc_right: + incr = 1, 0 + elif type = S.wc_down: + incr = 0, 1 + else: + return + icol, irow = w.lastselection + icol = icol + incr[0] + if icol < 0: icol = len(w.data)-1 + if icol >= len(w.data): icol = 0 + if 0 <= icol < len(w.data): + irow = irow + incr[1] + if irow < 0: irow = len(w.data[icol]) - 1 + if irow >= len(w.data[icol]): irow = 0 + else: + irow = 0 + if 0 <= icol < len(w.data) and 0 <= irow < len(w.data[icol]): + w.lastselection = icol, irow + string, action = w.data[icol][irow] + detail = (0, 0), 1, 1, 1 + action(w, string, (icol, irow), detail) + + +# Selection management +# TO DO: allow multiple selected entries + +def select(w, selection): # Public function to set the item selection + d = w.begindrawing() + hidesel(w, d) + w.selection = selection + showsel(w, d) + if w.selshown: lastselection = selection + +def hidesel(w, d): # Hide the selection, if shown + if w.selshown: invertsel(w, d) + +def showsel(w, d): # Show the selection, if hidden + if not w.selshown: invertsel(w, d) + +def invertsel(w, d): # Invert the selection, if valid + icol, irow = w.selection + if 0 <= icol < len(w.data) and 0 <= irow < len(w.data[icol]): + left = w.colstarts[icol] + right = w.colstarts[icol+1] + top = irow * w.lineheight + bottom = (irow+1) * w.lineheight + d.invert((left, top), (right, bottom)) + w.selshown = (not w.selshown) + + +# Demonstration + +def demo_action(w, string, (icol, irow), detail): # Action function for demo + select(w, (irow, icol)) + +def demo(): # Demonstration + da = demo_action # shorthand + col0 = [('a1', da), ('bbb1', da), ('c1', da)] + col1 = [('a2', da), ('bbb2', da)] + col2 = [('a3', da), ('b3', da), ('c3', da), ('d4', da), ('d5', da)] + col3 = [] + for i in range(1, 31): col3.append('xxx' + `i`, da) + data = [col0, col1, col2, col3] + w = open('tablewin.demo', data) + gwin.mainloop() + return w diff --git a/Lib/lib-stdwin/textwin.py b/Lib/lib-stdwin/textwin.py new file mode 100644 index 00000000000..2631ca4ee54 --- /dev/null +++ b/Lib/lib-stdwin/textwin.py @@ -0,0 +1,119 @@ +# Module 'textwin' + +# Text windows, a subclass of gwin + +import stdwin +import stdwinsupport +import gwin + +S = stdwinsupport # Shorthand + + +def fixsize(w): + docwidth, docheight = w.text.getrect()[1] + winheight = w.getwinsize()[1] + if winheight > docheight: docheight = winheight + w.setdocsize(0, docheight) + fixeditmenu(w) + +def cut(w, m, id): + s = w.text.getfocustext() + if s: + stdwin.setcutbuffer(s) + w.text.replace('') + fixsize(w) + +def copy(w, m, id): + s = w.text.getfocustext() + if s: + stdwin.setcutbuffer(s) + fixeditmenu(w) + +def paste(w, m, id): + w.text.replace(stdwin.getcutbuffer()) + fixsize(w) + +def addeditmenu(w): + m = w.editmenu = w.menucreate('Edit') + m.action = [] + m.additem('Cut', 'X') + m.action.append(cut) + m.additem('Copy', 'C') + m.action.append(copy) + m.additem('Paste', 'V') + m.action.append(paste) + +def fixeditmenu(w): + m = w.editmenu + f = w.text.getfocus() + can_copy = (f[0] < f[1]) + m.enable(1, can_copy) + if not w.readonly: + m.enable(0, can_copy) + m.enable(2, (stdwin.getcutbuffer() <> '')) + +def draw(w, area): # Draw method + w.text.draw(area) + +def size(w, newsize): # Size method + w.text.move((0, 0), newsize) + fixsize(w) + +def close(w): # Close method + del w.text # Break circular ref + gwin.close(w) + +def char(w, c): # Char method + w.text.replace(c) + fixsize(w) + +def backspace(w): # Backspace method + void = w.text.event(S.we_command, w, S.wc_backspace) + fixsize(w) + +def arrow(w, detail): # Arrow method + w.text.arrow(detail) + fixeditmenu(w) + +def mdown(w, detail): # Mouse down method + void = w.text.event(S.we_mouse_down, w, detail) + fixeditmenu(w) + +def mmove(w, detail): # Mouse move method + void = w.text.event(S.we_mouse_move, w, detail) + +def mup(w, detail): # Mouse up method + void = w.text.event(S.we_mouse_up, w, detail) + fixeditmenu(w) + +def activate(w): # Activate method + fixeditmenu(w) + +def open(title, str): # Display a string in a window + w = gwin.open(title) + w.readonly = 0 + w.text = w.textcreate((0, 0), w.getwinsize()) + w.text.replace(str) + w.text.setfocus(0, 0) + addeditmenu(w) + fixsize(w) + w.draw = draw + w.size = size + w.close = close + w.mdown = mdown + w.mmove = mmove + w.mup = mup + w.char = char + w.backspace = backspace + w.arrow = arrow + w.activate = activate + return w + +def open_readonly(title, str): # Same with char input disabled + w = open(title, str) + w.readonly = 1 + w.char = w.backspace = gwin.nop + # Disable Cut and Paste menu item; leave Copy alone + w.editmenu.enable(0, 0) + w.editmenu.enable(2, 0) + return w diff --git a/Lib/plat-irix5/DEVICE.py b/Lib/plat-irix5/DEVICE.py new file mode 100755 index 00000000000..00eddfc13f7 --- /dev/null +++ b/Lib/plat-irix5/DEVICE.py @@ -0,0 +1,423 @@ +#/************************************************************************** +# * * +# * Copyright (C) 1984, Silicon Graphics, Inc. * +# * * +# * These coded instructions, statements, and computer programs contain * +# * unpublished proprietary information of Silicon Graphics, Inc., and * +# * are protected by Federal copyright law. They may not be disclosed * +# * to third parties or copied or duplicated in any form, in whole or * +# * in part, without the prior written consent of Silicon Graphics, Inc. * +# * * +# **************************************************************************/ +#/* file with device definitions (see /usr/include/device.h) */ + +NULLDEV = 0 +BUTOFFSET = 1 +VALOFFSET = 256 +TIMOFFSET = 515 +XKBDOFFSET = 143 +INOFFSET = 1024 +OUTOFFSET = 1033 +BUTCOUNT = 190 +VALCOUNT = 27 +TIMCOUNT = 4 +XKBDCOUNT = 28 +INCOUNT = 8 +OUTCOUNT = 8 +# +# +# +# +BUT0 = 1 +BUT1 = 2 +BUT2 = 3 +BUT3 = 4 +BUT4 = 5 +BUT5 = 6 +BUT6 = 7 +BUT7 = 8 +BUT8 = 9 +BUT9 = 10 +BUT10 = 11 +BUT11 = 12 +BUT12 = 13 +BUT13 = 14 +BUT14 = 15 +BUT15 = 16 +BUT16 = 17 +BUT17 = 18 +BUT18 = 19 +BUT19 = 20 +BUT20 = 21 +BUT21 = 22 +BUT22 = 23 +BUT23 = 24 +BUT24 = 25 +BUT25 = 26 +BUT26 = 27 +BUT27 = 28 +BUT28 = 29 +BUT29 = 30 +BUT30 = 31 +BUT31 = 32 +BUT32 = 33 +BUT33 = 34 +BUT34 = 35 +BUT35 = 36 +BUT36 = 37 +BUT37 = 38 +BUT38 = 39 +BUT39 = 40 +BUT40 = 41 +BUT41 = 42 +BUT42 = 43 +BUT43 = 44 +BUT44 = 45 +BUT45 = 46 +BUT46 = 47 +BUT47 = 48 +BUT48 = 49 +BUT49 = 50 +BUT50 = 51 +BUT51 = 52 +BUT52 = 53 +BUT53 = 54 +BUT54 = 55 +BUT55 = 56 +BUT56 = 57 +BUT57 = 58 +BUT58 = 59 +BUT59 = 60 +BUT60 = 61 +BUT61 = 62 +BUT62 = 63 +BUT63 = 64 +BUT64 = 65 +BUT65 = 66 +BUT66 = 67 +BUT67 = 68 +BUT68 = 69 +BUT69 = 70 +BUT70 = 71 +BUT71 = 72 +BUT72 = 73 +BUT73 = 74 +BUT74 = 75 +BUT75 = 76 +BUT76 = 77 +BUT77 = 78 +BUT78 = 79 +BUT79 = 80 +BUT80 = 81 +BUT81 = 82 +BUT82 = 83 +MAXKBDBUT = 83 +BUT100 = 101 +BUT101 = 102 +BUT102 = 103 +BUT110 = 111 +BUT111 = 112 +BUT112 = 113 +BUT113 = 114 +BUT114 = 115 +BUT115 = 116 +BUT116 = 117 +BUT117 = 118 +BUT118 = 119 +BUT119 = 120 +BUT120 = 121 +BUT121 = 122 +BUT122 = 123 +BUT123 = 124 +BUT124 = 125 +BUT125 = 126 +BUT126 = 127 +BUT127 = 128 +BUT128 = 129 +BUT129 = 130 +BUT130 = 131 +BUT131 = 132 +BUT132 = 133 +BUT133 = 134 +BUT134 = 135 +BUT135 = 136 +BUT136 = 137 +BUT137 = 138 +BUT138 = 139 +BUT139 = 140 +BUT140 = 141 +BUT141 = 142 +BUT142 = 143 +BUT143 = 144 +BUT144 = 145 +BUT145 = 146 +BUT146 = 147 +BUT147 = 148 +BUT148 = 149 +BUT149 = 150 +BUT150 = 151 +BUT151 = 152 +BUT152 = 153 +BUT153 = 154 +BUT154 = 155 +BUT155 = 156 +BUT156 = 157 +BUT157 = 158 +BUT158 = 159 +BUT159 = 160 +BUT160 = 161 +BUT161 = 162 +BUT162 = 163 +BUT163 = 164 +BUT164 = 165 +BUT165 = 166 +BUT166 = 167 +BUT167 = 168 +BUT168 = 169 +BUT181 = 182 +BUT182 = 183 +BUT183 = 184 +BUT184 = 185 +BUT185 = 186 +BUT186 = 187 +BUT187 = 188 +BUT188 = 189 +BUT189 = 190 +MOUSE1 = 101 +MOUSE2 = 102 +MOUSE3 = 103 +LEFTMOUSE = 103 +MIDDLEMOUSE = 102 +RIGHTMOUSE = 101 +LPENBUT = 104 +BPAD0 = 105 +BPAD1 = 106 +BPAD2 = 107 +BPAD3 = 108 +LPENVALID = 109 +SWBASE = 111 +SW0 = 111 +SW1 = 112 +SW2 = 113 +SW3 = 114 +SW4 = 115 +SW5 = 116 +SW6 = 117 +SW7 = 118 +SW8 = 119 +SW9 = 120 +SW10 = 121 +SW11 = 122 +SW12 = 123 +SW13 = 124 +SW14 = 125 +SW15 = 126 +SW16 = 127 +SW17 = 128 +SW18 = 129 +SW19 = 130 +SW20 = 131 +SW21 = 132 +SW22 = 133 +SW23 = 134 +SW24 = 135 +SW25 = 136 +SW26 = 137 +SW27 = 138 +SW28 = 139 +SW29 = 140 +SW30 = 141 +SW31 = 142 +SBBASE = 182 +SBPICK = 182 +SBBUT1 = 183 +SBBUT2 = 184 +SBBUT3 = 185 +SBBUT4 = 186 +SBBUT5 = 187 +SBBUT6 = 188 +SBBUT7 = 189 +SBBUT8 = 190 +AKEY = 11 +BKEY = 36 +CKEY = 28 +DKEY = 18 +EKEY = 17 +FKEY = 19 +GKEY = 26 +HKEY = 27 +IKEY = 40 +JKEY = 34 +KKEY = 35 +LKEY = 42 +MKEY = 44 +NKEY = 37 +OKEY = 41 +PKEY = 48 +QKEY = 10 +RKEY = 24 +SKEY = 12 +TKEY = 25 +UKEY = 33 +VKEY = 29 +WKEY = 16 +XKEY = 21 +YKEY = 32 +ZKEY = 20 +ZEROKEY = 46 +ONEKEY = 8 +TWOKEY = 14 +THREEKEY = 15 +FOURKEY = 22 +FIVEKEY = 23 +SIXKEY = 30 +SEVENKEY = 31 +EIGHTKEY = 38 +NINEKEY = 39 +BREAKKEY = 1 +SETUPKEY = 2 +CTRLKEY = 3 +LEFTCTRLKEY = CTRLKEY +CAPSLOCKKEY = 4 +RIGHTSHIFTKEY = 5 +LEFTSHIFTKEY = 6 +NOSCRLKEY = 13 +ESCKEY = 7 +TABKEY = 9 +RETKEY = 51 +SPACEKEY = 83 +LINEFEEDKEY = 60 +BACKSPACEKEY = 61 +DELKEY = 62 +SEMICOLONKEY = 43 +PERIODKEY = 52 +COMMAKEY = 45 +QUOTEKEY = 50 +ACCENTGRAVEKEY = 55 +MINUSKEY = 47 +VIRGULEKEY = 53 +BACKSLASHKEY = 57 +EQUALKEY = 54 +LEFTBRACKETKEY = 49 +RIGHTBRACKETKEY = 56 +LEFTARROWKEY = 73 +DOWNARROWKEY = 74 +RIGHTARROWKEY = 80 +UPARROWKEY = 81 +PAD0 = 59 +PAD1 = 58 +PAD2 = 64 +PAD3 = 65 +PAD4 = 63 +PAD5 = 69 +PAD6 = 70 +PAD7 = 67 +PAD8 = 68 +PAD9 = 75 +PADPF1 = 72 +PADPF2 = 71 +PADPF3 = 79 +PADPF4 = 78 +PADPERIOD = 66 +PADMINUS = 76 +PADCOMMA = 77 +PADENTER = 82 +LEFTALTKEY = 143 +RIGHTALTKEY = 144 +RIGHTCTRLKEY = 145 +F1KEY = 146 +F2KEY = 147 +F3KEY = 148 +F4KEY = 149 +F5KEY = 150 +F6KEY = 151 +F7KEY = 152 +F8KEY = 153 +F9KEY = 154 +F10KEY = 155 +F11KEY = 156 +F12KEY = 157 +PRINTSCREENKEY = 158 +SCROLLLOCKKEY = 159 +PAUSEKEY = 160 +INSERTKEY = 161 +HOMEKEY = 162 +PAGEUPKEY = 163 +ENDKEY = 164 +PAGEDOWNKEY = 165 +NUMLOCKKEY = 166 +PADVIRGULEKEY = 167 +PADASTERKEY = 168 +PADPLUSKEY = 169 +SGIRESERVED = 256 +DIAL0 = 257 +DIAL1 = 258 +DIAL2 = 259 +DIAL3 = 260 +DIAL4 = 261 +DIAL5 = 262 +DIAL6 = 263 +DIAL7 = 264 +DIAL8 = 265 +MOUSEX = 266 +MOUSEY = 267 +LPENX = 268 +LPENY = 269 +BPADX = 270 +BPADY = 271 +CURSORX = 272 +CURSORY = 273 +GHOSTX = 274 +GHOSTY = 275 +SBTX = 276 +SBTY = 277 +SBTZ = 278 +SBRX = 279 +SBRY = 280 +SBRZ = 281 +SBPERIOD = 282 +TIMER0 = 515 +TIMER1 = 516 +TIMER2 = 517 +TIMER3 = 518 +KEYBD = 513 +RAWKEYBD = 514 +VALMARK = 523 +GERROR = 524 +REDRAW = 528 +WMSEND = 529 +WMREPLY = 530 +WMGFCLOSE = 531 +WMTXCLOSE = 532 +MODECHANGE = 533 +INPUTCHANGE = 534 +QFULL = 535 +PIECECHANGE = 536 +WINCLOSE = 537 +QREADERROR = 538 +WINFREEZE = 539 +WINTHAW = 540 +REDRAWICONIC = 541 +WINQUIT = 542 +DEPTHCHANGE = 543 +KEYBDFNAMES = 544 +KEYBDFSTRINGS = 545 +WINSHUT = 546 +INPUT0 = 1024 +INPUT1 = 1025 +INPUT2 = 1026 +INPUT3 = 1027 +INPUT4 = 1028 +INPUT5 = 1029 +INPUT6 = 1030 +INPUT7 = 1032 +OUTPUT0 = 1033 +OUTPUT1 = 1034 +OUTPUT2 = 1035 +OUTPUT3 = 1036 +OUTPUT4 = 1037 +OUTPUT5 = 1038 +OUTPUT6 = 1039 +OUTPUT7 = 1040 +MAXSGIDEVICE = 20000 +MENUBUTTON = RIGHTMOUSE diff --git a/Lib/plat-irix5/GL.py b/Lib/plat-irix5/GL.py new file mode 100755 index 00000000000..35487a74fab --- /dev/null +++ b/Lib/plat-irix5/GL.py @@ -0,0 +1,365 @@ +# Constants defined in + +#************************************************************************** +#* * +#* Copyright (C) 1984, Silicon Graphics, Inc. * +#* * +#* These coded instructions, statements, and computer programs contain * +#* unpublished proprietary information of Silicon Graphics, Inc., and * +#* are protected by Federal copyright law. They may not be disclosed * +#* to third parties or copied or duplicated in any form, in whole or * +#* in part, without the prior written consent of Silicon Graphics, Inc. * +#* * +#************************************************************************** + +# Graphics Libary constants + +# Booleans +TRUE = 1 +FALSE = 0 + +# maximum X and Y screen coordinates +XMAXSCREEN = 1279 +YMAXSCREEN = 1023 +XMAXMEDIUM = 1023 # max for medium res monitor +YMAXMEDIUM = 767 +XMAX170 = 645 # max for RS-170 +YMAX170 = 484 +XMAXPAL = 779 # max for PAL +YMAXPAL = 574 + +# various hardware/software limits +ATTRIBSTACKDEPTH = 10 +VPSTACKDEPTH = 8 +MATRIXSTACKDEPTH = 32 +NAMESTACKDEPTH = 1025 +STARTTAG = -2 +ENDTAG = -3 +CPOSX_INVALID = -(2*XMAXSCREEN) + +# names for colors in color map loaded by greset +BLACK = 0 +RED = 1 +GREEN = 2 +YELLOW = 3 +BLUE = 4 +MAGENTA = 5 +CYAN = 6 +WHITE = 7 + +# popup colors +PUP_CLEAR = 0 +PUP_COLOR = 1 +PUP_BLACK = 2 +PUP_WHITE = 3 + +# defines for drawmode +NORMALDRAW = 0 +PUPDRAW = 1 +OVERDRAW = 2 +UNDERDRAW = 3 +CURSORDRAW = 4 + +# defines for defpattern +PATTERN_16 = 16 +PATTERN_32 = 32 +PATTERN_64 = 64 + +PATTERN_16_SIZE = 16 +PATTERN_32_SIZE = 64 +PATTERN_64_SIZE = 256 + +# defines for readsource +SRC_AUTO = 0 +SRC_FRONT = 1 +SRC_BACK = 2 +SRC_ZBUFFER = 3 +SRC_PUP = 4 +SRC_OVER = 5 +SRC_UNDER = 6 +SRC_FRAMEGRABBER = 7 + +# defines for blendfunction +BF_ZERO = 0 +BF_ONE = 1 +BF_DC = 2 +BF_SC = 2 +BF_MDC = 3 +BF_MSC = 3 +BF_SA = 4 +BF_MSA = 5 +BF_DA = 6 +BF_MDA = 7 + +# defines for zfunction +ZF_NEVER = 0 +ZF_LESS = 1 +ZF_EQUAL = 2 +ZF_LEQUAL = 3 +ZF_GREATER = 4 +ZF_NOTEQUAL = 5 +ZF_GEQUAL = 6 +ZF_ALWAYS = 7 + +# defines for zsource +ZSRC_DEPTH = 0 +ZSRC_COLOR = 1 + +# defines for pntsmooth +SMP_OFF = 0 +SMP_ON = 1 + +# defines for linesmooth +SML_OFF = 0 +SML_ON = 1 + +# defines for setpup +PUP_NONE = 0 +PUP_GREY = 1 + +# defines for glcompat +GLC_OLDPOLYGON = 0 +GLC_ZRANGEMAP = 1 + +# defines for curstype +C16X1 = 0 +C16X2 = 1 +C32X1 = 2 +C32X2 = 3 +CCROSS = 4 + +# defines for shademodel +FLAT = 0 +GOURAUD = 1 + +# defines for logicop +### LO_ZERO = 0x0 +### LO_AND = 0x1 +### LO_ANDR = 0x2 +### LO_SRC = 0x3 +### LO_ANDI = 0x4 +### LO_DST = 0x5 +### LO_XOR = 0x6 +### LO_OR = 0x7 +### LO_NOR = 0x8 +### LO_XNOR = 0x9 +### LO_NDST = 0xa +### LO_ORR = 0xb +### LO_NSRC = 0xc +### LO_ORI = 0xd +### LO_NAND = 0xe +### LO_ONE = 0xf + + +# +# START defines for getgdesc +# + +GD_XPMAX = 0 +GD_YPMAX = 1 +GD_XMMAX = 2 +GD_YMMAX = 3 +GD_ZMIN = 4 +GD_ZMAX = 5 +GD_BITS_NORM_SNG_RED = 6 +GD_BITS_NORM_SNG_GREEN = 7 +GD_BITS_NORM_SNG_BLUE = 8 +GD_BITS_NORM_DBL_RED = 9 +GD_BITS_NORM_DBL_GREEN = 10 +GD_BITS_NORM_DBL_BLUE = 11 +GD_BITS_NORM_SNG_CMODE = 12 +GD_BITS_NORM_DBL_CMODE = 13 +GD_BITS_NORM_SNG_MMAP = 14 +GD_BITS_NORM_DBL_MMAP = 15 +GD_BITS_NORM_ZBUFFER = 16 +GD_BITS_OVER_SNG_CMODE = 17 +GD_BITS_UNDR_SNG_CMODE = 18 +GD_BITS_PUP_SNG_CMODE = 19 +GD_BITS_NORM_SNG_ALPHA = 21 +GD_BITS_NORM_DBL_ALPHA = 22 +GD_BITS_CURSOR = 23 +GD_OVERUNDER_SHARED = 24 +GD_BLEND = 25 +GD_CIFRACT = 26 +GD_CROSSHAIR_CINDEX = 27 +GD_DITHER = 28 +GD_LINESMOOTH_CMODE = 30 +GD_LINESMOOTH_RGB = 31 +GD_LOGICOP = 33 +GD_NSCRNS = 35 +GD_NURBS_ORDER = 36 +GD_NBLINKS = 37 +GD_NVERTEX_POLY = 39 +GD_PATSIZE_64 = 40 +GD_PNTSMOOTH_CMODE = 41 +GD_PNTSMOOTH_RGB = 42 +GD_PUP_TO_OVERUNDER = 43 +GD_READSOURCE = 44 +GD_READSOURCE_ZBUFFER = 48 +GD_STEREO = 50 +GD_SUBPIXEL_LINE = 51 +GD_SUBPIXEL_PNT = 52 +GD_SUBPIXEL_POLY = 53 +GD_TRIMCURVE_ORDER = 54 +GD_WSYS = 55 +GD_ZDRAW_GEOM = 57 +GD_ZDRAW_PIXELS = 58 +GD_SCRNTYPE = 61 +GD_TEXTPORT = 62 +GD_NMMAPS = 63 +GD_FRAMEGRABBER = 64 +GD_TIMERHZ = 66 +GD_DBBOX = 67 +GD_AFUNCTION = 68 +GD_ALPHA_OVERUNDER = 69 +GD_BITS_ACBUF = 70 +GD_BITS_ACBUF_HW = 71 +GD_BITS_STENCIL = 72 +GD_CLIPPLANES = 73 +GD_FOGVERTEX = 74 +GD_LIGHTING_TWOSIDE = 76 +GD_POLYMODE = 77 +GD_POLYSMOOTH = 78 +GD_SCRBOX = 79 +GD_TEXTURE = 80 + +# return value for inquiries when there is no limit +GD_NOLIMIT = 2 + +# return values for GD_WSYS +GD_WSYS_NONE = 0 +GD_WSYS_4S = 1 + +# return values for GD_SCRNTYPE +GD_SCRNTYPE_WM = 0 +GD_SCRNTYPE_NOWM = 1 + +# +# END defines for getgdesc +# + + +# +# START NURBS interface definitions +# + +# NURBS Rendering Properties +N_PIXEL_TOLERANCE = 1 +N_CULLING = 2 +N_DISPLAY = 3 +N_ERRORCHECKING = 4 +N_SUBDIVISIONS = 5 +N_S_STEPS = 6 +N_T_STEPS = 7 +N_TILES = 8 + +N_SHADED = 1.0 + +# --------------------------------------------------------------------------- +# FLAGS FOR NURBS SURFACES AND CURVES +# +# Bit: 9876 5432 1 0 +# |tttt|nnnn|f|r| : r - 1 bit = 1 if rational coordinate exists +# : f - 1 bit = 1 if rational coordinate is before rest +# : = 0 if rational coordinate is after rest +# : nnnn - 4 bits for number of coordinates +# : tttt - 4 bits for type of data (color, position, etc.) +# +# NURBS data type +# N_T_ST 0 parametric space data +# N_T_XYZ 1 model space data +# +# rational or non-rational data and position in memory +# N_NONRATIONAL 0 non-rational data +# N_RATAFTER 1 rational data with rat coord after rest +# N_RATBEFORE 3 rational data with rat coord before rest +# +# N_MKFLAG(a,b,c) ((a<<6) | (b<<2) | c) +# +# --------------------------------------------------------------------------- +# +N_ST = 0x8 # N_MKFLAG( N_T_ST, 2, N_NONRATIONAL ) +N_STW = 0xd # N_MKFLAG( N_T_ST, 3, N_RATAFTER ) +N_WST = 0xf # N_MKFLAG( N_T_ST, 3, N_RATBEFORE ) +N_XYZ = 0x4c # N_MKFLAG( N_T_XYZ, 3, N_NONRATIONAL ) +N_XYZW = 0x51 # N_MKFLAG( N_T_XYZ, 4, N_RATAFTER ) +N_WXYZ = 0x53 # N_MKFLAG( N_T_XYZ, 4, N_RATBEFORE ) + +# +# END NURBS interface definitions +# + + +# +# START lighting model defines +# + +LMNULL = 0.0 + +# MATRIX modes +MSINGLE = 0 +MPROJECTION = 1 +MVIEWING = 2 + +# LIGHT constants +MAXLIGHTS = 8 +MAXRESTRICTIONS = 4 + +# MATERIAL properties +DEFMATERIAL = 0 +EMISSION = 1 +AMBIENT = 2 +DIFFUSE = 3 +SPECULAR = 4 +SHININESS = 5 +COLORINDEXES = 6 +ALPHA = 7 + +# LIGHT properties +DEFLIGHT = 100 +LCOLOR = 101 +POSITION = 102 + +# LIGHTINGMODEL properties +DEFLMODEL = 200 +LOCALVIEWER = 201 +ATTENUATION = 202 + +# TARGET constants +MATERIAL = 1000 +LIGHT0 = 1100 +LIGHT1 = 1101 +LIGHT2 = 1102 +LIGHT3 = 1103 +LIGHT4 = 1104 +LIGHT5 = 1105 +LIGHT6 = 1106 +LIGHT7 = 1107 +LMODEL = 1200 + +# lmcolor modes +LMC_COLOR = 0 +LMC_EMISSION = 1 +LMC_AMBIENT = 2 +LMC_DIFFUSE = 3 +LMC_SPECULAR = 4 +LMC_AD = 5 +LMC_NULL = 6 + +# +# END lighting model defines +# + + +# +# START distributed graphics library defines +# + +DGLSINK = 0 # sink connection +DGLLOCAL = 1 # local connection +DGLTSOCKET = 2 # tcp socket connection +DGL4DDN = 3 # 4DDN (DECnet) + +# +# END distributed graphics library defines +# diff --git a/Lib/plat-irix5/panel.py b/Lib/plat-irix5/panel.py new file mode 100755 index 00000000000..eb115086f66 --- /dev/null +++ b/Lib/plat-irix5/panel.py @@ -0,0 +1,281 @@ +# Module 'panel' +# +# Support for the Panel library. +# Uses built-in module 'pnl'. +# Applciations should use 'panel.function' instead of 'pnl.function'; +# most 'pnl' functions are transparently exported by 'panel', +# but dopanel() is overridden and you have to use this version +# if you want to use callbacks. + + +import pnl + + +debug = 0 + + +# Test if an object is a list. +# +def is_list(x): + return type(x) = type([]) + + +# Reverse a list. +# +def reverse(list): + res = [] + for item in list: + res.insert(0, item) + return res + + +# Get an attribute of a list, which may itself be another list. +# Don't use 'prop' for name. +# +def getattrlist(list, name): + for item in list: + if item and is_list(item) and item[0] = name: + return item[1:] + return [] + + +# Get a property of a list, which may itself be another list. +# +def getproplist(list, name): + for item in list: + if item and is_list(item) and item[0] = 'prop': + if len(item) > 1 and item[1] = name: + return item[2:] + return [] + + +# Test if an actuator description contains the property 'end-of-group' +# +def is_endgroup(list): + x = getproplist(list, 'end-of-group') + return (x and x[0] = '#t') + + +# Neatly display an actuator definition given as S-expression +# the prefix string is printed before each line. +# +def show_actuator(prefix, a): + for item in a: + if not is_list(item): + print prefix, item + elif item and item[0] = 'al': + print prefix, 'Subactuator list:' + for a in item[1:]: + show_actuator(prefix + ' ', a) + elif len(item) = 2: + print prefix, item[0], '=>', item[1] + elif len(item) = 3 and item[0] = 'prop': + print prefix, 'Prop', item[1], '=>', + print item[2] + else: + print prefix, '?', item + + +# Neatly display a panel. +# +def show_panel(prefix, p): + for item in p: + if not is_list(item): + print prefix, item + elif item and item[0] = 'al': + print prefix, 'Actuator list:' + for a in item[1:]: + show_actuator(prefix + ' ', a) + elif len(item) = 2: + print prefix, item[0], '=>', item[1] + elif len(item) = 3 and item[0] = 'prop': + print prefix, 'Prop', item[1], '=>', + print item[2] + else: + print prefix, '?', item + + +# Exception raised by build_actuator or build_panel. +# +panel_error = 'panel error' + + +# Dummy callback used to initialize the callbacks. +# +def dummy_callback(arg): + pass + + +# Assign attributes to members of the target. +# Attribute names in exclist are ignored. +# The member name is the attribute name prefixed with the prefix. +# +def assign_members(target, attrlist, exclist, prefix): + for item in attrlist: + if is_list(item) and len(item) = 2 and item[0] not in exclist: + name, value = item[0], item[1] + ok = 1 + if value[0] in '-0123456789': + value = eval(value) + elif value[0] = '"': + value = value[1:-1] + elif value = 'move-then-resize': + # Strange default set by Panel Editor... + ok = 0 + else: + print 'unknown value', value, 'for', name + ok = 0 + if ok: + lhs = 'target.' + prefix + name + stmt = lhs + '=' + `value` + if debug: print 'exec', stmt + try: + exec(stmt + '\n') + except KeyboardInterrupt: # Don't catch this! + raise KeyboardInterrupt + except: + print 'assign failed:', stmt + + +# Build a real actuator from an actuator descriptior. +# Return a pair (actuator, name). +# +def build_actuator(descr): + namelist = getattrlist(descr, 'name') + if namelist: + # Assume it is a string + actuatorname = namelist[0][1:-1] + else: + actuatorname = '' + type = descr[0] + if type[:4] = 'pnl_': type = type[4:] + act = pnl.mkact(type) + act.downfunc = act.activefunc = act.upfunc = dummy_callback + # + assign_members(act, descr[1:], ('al', 'data', 'name'), '') + # + # Treat actuator-specific data + # + datalist = getattrlist(descr, 'data') + prefix = '' + if type[-4:] = 'puck': + prefix = 'puck_' + elif type = 'mouse': + prefix = 'mouse_' + assign_members(act, datalist, (), prefix) + # + return act, actuatorname + + +# Build all sub-actuators and add them to the super-actuator. +# The super-actuator must already have been added to the panel. +# Sub-actuators with defined names are added as members to the panel +# so they can be referenced as p.name. +# +# Note: I have no idea how panel.endgroup() works when applied +# to a sub-actuator. +# +def build_subactuators(panel, super_act, al): + # + # This is nearly the same loop as below in build_panel(), + # except a call is made to addsubact() instead of addact(). + # + for a in al: + act, name = build_actuator(a) + act.addsubact(super_act) + if name: + stmt = 'panel.' + name + ' = act' + if debug: print 'exec', stmt + exec(stmt + '\n') + if is_endgroup(a): + panel.endgroup() + sub_al = getattrlist(a, 'al') + if sub_al: + build_subactuators(panel, act, sub_al) + # + # Fix the actuator to which whe just added subactuators. + # This can't hurt (I hope) and is needed for the scroll actuator. + # + super_act.fixact() + + +# Build a real panel from a panel definition. +# Return a panel object p, where for each named actuator a, p.name is a +# reference to a. +# +def build_panel(descr): + # + # Sanity check + # + if (not descr) or descr[0] <> 'panel': + raise panel_error, 'panel description must start with "panel"' + # + if debug: show_panel('', descr) + # + # Create an empty panel + # + panel = pnl.mkpanel() + # + # Assign panel attributes + # + assign_members(panel, descr[1:], ('al'), '') + # + # Look for actuator list + # + al = getattrlist(descr, 'al') + # + # The order in which actuators are created is important + # because of the endgroup() operator. + # Unfortunately the Panel Editor outputs the actuator list + # in reverse order, so we reverse it here. + # + al = reverse(al) + # + for a in al: + act, name = build_actuator(a) + act.addact(panel) + if name: + stmt = 'panel.' + name + ' = act' + exec(stmt + '\n') + if is_endgroup(a): + panel.endgroup() + sub_al = getattrlist(a, 'al') + if sub_al: + build_subactuators(panel, act, sub_al) + # + return panel + + +# Wrapper around pnl.dopanel() which calls call-back functions. +# +def my_dopanel(): + # Extract only the first 4 elements to allow for future expansion + a, down, active, up = pnl.dopanel()[:4] + if down: + down.downfunc(down) + if active: + active.activefunc(active) + if up: + up.upfunc(up) + return a + + +# Create one or more panels from a description file (S-expressions) +# generated by the Panel Editor. +# +def defpanellist(file): + import parser + descrlist = parser.parse_file(open(file, 'r')) + panellist = [] + for descr in descrlist: + panellist.append(build_panel(descr)) + return panellist + + +# Import everything from built-in method pnl, so the user can always +# use panel.foo() instead of pnl.foo(). +# This gives *no* performance penalty once this module is imported. +# +from pnl import * # for export + +dopanel = my_dopanel # override pnl.dopanel diff --git a/Lib/plat-irix5/panelparser.py b/Lib/plat-irix5/panelparser.py new file mode 100755 index 00000000000..9c9ee022750 --- /dev/null +++ b/Lib/plat-irix5/panelparser.py @@ -0,0 +1,128 @@ +# Module 'parser' +# +# Parse S-expressions output by the Panel Editor +# (which is written in Scheme so it can't help writing S-expressions). +# +# See notes at end of file. + + +whitespace = ' \t\n' +operators = '()\'' +separators = operators + whitespace + ';' + '"' + + +# Tokenize a string. +# Return a list of tokens (strings). +# +def tokenize_string(s): + tokens = [] + while s: + c = s[:1] + if c in whitespace: + s = s[1:] + elif c = ';': + s = '' + elif c = '"': + n = len(s) + i = 1 + while i < n: + c = s[i] + i = i+1 + if c = '"': break + if c = '\\': i = i+1 + tokens.append(s[:i]) + s = s[i:] + elif c in operators: + tokens.append(c) + s = s[1:] + else: + n = len(s) + i = 1 + while i < n: + if s[i] in separators: break + i = i+1 + tokens.append(s[:i]) + s = s[i:] + return tokens + + +# Tokenize a whole file (given as file object, not as file name). +# Return a list of tokens (strings). +# +def tokenize_file(fp): + tokens = [] + while 1: + line = fp.readline() + if not line: break + tokens = tokens + tokenize_string(line) + return tokens + + +# Exception raised by parse_exr. +# +syntax_error = 'syntax error' + + +# Parse an S-expression. +# Input is a list of tokens as returned by tokenize_*(). +# Return a pair (expr, tokens) +# where expr is a list representing the s-expression, +# and tokens contains the remaining tokens. +# May raise syntax_error. +# +def parse_expr(tokens): + if (not tokens) or tokens[0] <> '(': + raise syntax_error, 'expected "("' + tokens = tokens[1:] + expr = [] + while 1: + if not tokens: + raise syntax_error, 'missing ")"' + if tokens[0] = ')': + return expr, tokens[1:] + elif tokens[0] = '(': + subexpr, tokens = parse_expr(tokens) + expr.append(subexpr) + else: + expr.append(tokens[0]) + tokens = tokens[1:] + + +# Parse a file (given as file object, not as file name). +# Return a list of parsed S-expressions found at the top level. +# +def parse_file(fp): + tokens = tokenize_file(fp) + exprlist = [] + while tokens: + expr, tokens = parse_expr(tokens) + exprlist.append(expr) + return exprlist + + +# EXAMPLE: +# +# The input +# '(hip (hop hur-ray))' +# +# passed to tokenize_string() returns the token list +# ['(', 'hip', '(', 'hop', 'hur-ray', ')', ')'] +# +# When this is passed to parse_expr() it returns the expression +# ['hip', ['hop', 'hur-ray']] +# plus an empty token list (because there are no tokens left. +# +# When a file containing the example is passed to parse_file() it returns +# a list whose only element is the output of parse_expr() above: +# [['hip', ['hop', 'hur-ray']]] + + +# TOKENIZING: +# +# Comments start with semicolon (;) and continue till the end of the line. +# +# Tokens are separated by whitespace, except the following characters +# always form a separate token (outside strings): +# ( ) ' +# Strings are enclosed in double quotes (") and backslash (\) is used +# as escape character in strings. diff --git a/Lib/poly.py b/Lib/poly.py new file mode 100644 index 00000000000..abac4c847c4 --- /dev/null +++ b/Lib/poly.py @@ -0,0 +1,55 @@ +# module 'poly' -- Polynomials + +# A polynomial is represented by a list of coefficients, e.g., +# [1, 10, 5] represents 1*x**0 + 10*x**1 + 5*x**2 (or 1 + 10x + 5x**2). +# There is no way to suppress internal zeros; trailing zeros are +# taken out by normalize(). + +def normalize(p): # Strip unnecessary zero coefficients + n = len(p) + while p: + if p[n-1]: return p[:n] + n = n-1 + return [] + +def plus(a, b): + if len(a) < len(b): a, b = b, a # make sure a is the longest + res = a[:] # make a copy + for i in range(len(b)): + res[i] = res[i] + b[i] + return normalize(res) + +def minus(a, b): + if len(a) < len(b): a, b = b, a # make sure a is the longest + res = a[:] # make a copy + for i in range(len(b)): + res[i] = res[i] - b[i] + return normalize(res) + +def one(power, coeff): # Representation of coeff * x**power + res = [] + for i in range(power): res.append(0) + return res + [coeff] + +def times(a, b): + res = [] + for i in range(len(a)): + for j in range(len(b)): + res = plus(res, one(i+j, a[i]*b[j])) + return res + +def power(a, n): # Raise polynomial a to the positive integral power n + if n = 0: return [1] + if n = 1: return a + if n/2*2 = n: + b = power(a, n/2) + return times(b, b) + return times(power(a, n-1), a) + +def der(a): # First derivative + res = a[1:] + for i in range(len(res)): + res[i] = res[i] * (i+1) + return res + +# Computing a primitive function would require rational arithmetic... diff --git a/Lib/posixpath.py b/Lib/posixpath.py new file mode 100644 index 00000000000..e314cb3abfd --- /dev/null +++ b/Lib/posixpath.py @@ -0,0 +1,124 @@ +# Module 'path' -- common operations on POSIX pathnames + +import posix + + +# Intelligent pathname concatenation. +# Inserts a '/' unless the first part is empty or already ends in '/'. +# Ignores the first part altogether if the second part is absolute +# (begins with '/'). +# +def cat(a, b): + if b[:1] = '/': return b + if a = '' or a[-1:] = '/': return a + b + return a + '/' + b + + +# Split a path in head (empty or ending in '/') and tail (no '/'). +# The tail will be empty if the path ends in '/'. +# +def split(p): + head, tail = '', '' + for c in p: + tail = tail + c + if c = '/': + head, tail = head + tail, '' + return head, tail + + +# Return the tail (basename) part of a path. +# +def basename(p): + return split(p)[1] + + +# Return the longest prefix of all list elements. +# +def commonprefix(m): + if not m: return '' + prefix = m[0] + for item in m: + for i in range(len(prefix)): + if prefix[:i+1] <> item[:i+1]: + prefix = prefix[:i] + if i = 0: return '' + break + return prefix + + +# Does a file/directory exist? +# +def exists(path): + try: + st = posix.stat(path) + except posix.error: + return 0 + return 1 + + +# Is a path a posix directory? +# +def isdir(path): + try: + st = posix.stat(path) + except posix.error: + return 0 + return st[0] / 4096 = 4 # S_IFDIR + + +# Is a path a symbolic link? +# This will always return false on systems where posix.lstat doesn't exist. +# +def islink(path): + try: + st = posix.lstat(path) + except (posix.error, NameError): + return 0 + return st[0] / 4096 = 10 # S_IFLNK + + +_mounts = [] + +def _getmounts(): + import commands, string + mounts = [] + data = commands.getoutput('/etc/mount') + lines = string.splitfields(data, '\n') + for line in lines: + words = string.split(line) + if len(words) >= 3 and words[1] = 'on': + mounts.append(words[2]) + return mounts + + +# Is a path a mount point? +# This only works for normalized, absolute paths, +# and only if the mount table as printed by /etc/mount is correct. +# Sorry. +# +def ismount(path): + if not _mounts: + _mounts[:] = _getmounts() + return path in _mounts + + +# Directory tree walk. +# For each directory under top (including top itself), +# func(arg, dirname, filenames) is called, where dirname +# is the name of the directory and filenames is the list of +# files (and subdirectories etc.) in the directory. +# func may modify the filenames list, to implement a filter, +# or to impose a different order of visiting. +# +def walk(top, func, arg): + try: + names = posix.listdir(top) + except posix.error: + return + func(arg, top, names) + exceptions = ('.', '..') + for name in names: + if name not in exceptions: + name = cat(top, name) + if isdir(name): + walk(name, func, arg) diff --git a/Lib/rand.py b/Lib/rand.py new file mode 100644 index 00000000000..06164833284 --- /dev/null +++ b/Lib/rand.py @@ -0,0 +1,12 @@ +# Module 'rand' + +import whrandom + +def srand(seed): + whrandom.seed(seed%256, seed/256%256, seed/65536%256) + +def rand(): + return int(whrandom.random() * 32768.0) % 32768 + +def choice(seq): + return seq[rand() % len(seq)] diff --git a/Lib/shutil.py b/Lib/shutil.py new file mode 100644 index 00000000000..cf633967ee6 --- /dev/null +++ b/Lib/shutil.py @@ -0,0 +1,70 @@ +# Module 'shutil' -- utility functions usable in a shell-like program + +import posix +import path + +MODEBITS = 010000 # Lower 12 mode bits +# Change this to 01000 (9 mode bits) to avoid copying setuid etc. + +# Copy data from src to dst +# +def copyfile(src, dst): + fsrc = open(src, 'r') + fdst = open(dst, 'w') + while 1: + buf = fsrc.read(16*1024) + if not buf: break + fdst.write(buf) + +# Copy mode bits from src to dst +# +def copymode(src, dst): + st = posix.stat(src) + mode = divmod(st[0], MODEBITS)[1] + posix.chmod(dst, mode) + +# Copy all stat info (mode bits, atime and mtime) from src to dst +# +def copystat(src, dst): + st = posix.stat(src) + mode = divmod(st[0], MODEBITS)[1] + posix.chmod(dst, mode) + posix.utimes(dst, st[7:9]) + +# Copy data and mode bits ("cp src dst") +# +def copy(src, dst): + copyfile(src, dst) + copymode(src, dst) + +# Copy data and all stat info ("cp -p src dst") +# +def copy2(src, dst): + copyfile(src, dst) + copystat(src, dst) + +# Recursively copy a directory tree. +# The destination must not already exist. +# +def copytree(src, dst): + names = posix.listdir(src) + posix.mkdir(dst, 0777) + dot_dotdot = '.', '..' + for name in names: + if name not in dot_dotdot: + srcname = path.cat(src, name) + dstname = path.cat(dst, name) + #print 'Copying', srcname, 'to', dstname + try: + #if path.islink(srcname): + # linkto = posix.readlink(srcname) + # posix.symlink(linkto, dstname) + #elif path.isdir(srcname): + if path.isdir(srcname): + copytree(srcname, dstname) + else: + copy2(srcname, dstname) + # XXX What about devices, sockets etc.? + except posix.error, why: + print 'Could not copy', srcname, 'to', dstname, + print '(', why[1], ')' diff --git a/Lib/statcache.py b/Lib/statcache.py new file mode 100644 index 00000000000..eeb0ca41977 --- /dev/null +++ b/Lib/statcache.py @@ -0,0 +1,90 @@ +# Module 'statcache' +# +# Maintain a cache of file stats. +# There are functions to reset the cache or to selectively remove items. + +import posix + + +# The cache. +# Keys are pathnames, values are `posix.stat' outcomes. +# +cache = {} + + +# Stat a file, possibly out of the cache. +# +def stat(path): + try: + return cache[path] + except RuntimeError: + pass + cache[path] = ret = posix.stat(path) + return ret + + +# Reset the cache completely. +# Hack: to reset a global variable, we import this module. +# +def reset(): + import statcache + # Check that we really imported the same module + if cache is not statcache.cache: + raise 'sorry, statcache identity crisis' + statcache.cache = {} + + +# Remove a given item from the cache, if it exists. +# +def forget(path): + try: + del cache[path] + except RuntimeError: + pass + + +# Remove all pathnames with a given prefix. +# +def forget_prefix(prefix): + n = len(prefix) + for path in cache.keys(): + if path[:n] = prefix: + del cache[path] + + +# Forget about a directory and all entries in it, but not about +# entries in subdirectories. +# +def forget_dir(prefix): + if prefix[-1:] = '/' and prefix <> '/': + prefix = prefix[:-1] + forget(prefix) + if prefix[-1:] <> '/': + prefix = prefix + '/' + n = len(prefix) + for path in cache.keys(): + if path[:n] = prefix: + rest = path[n:] + if rest[-1:] = '/': rest = rest[:-1] + if '/' not in rest: + del cache[path] + + +# Remove all pathnames except with a given prefix. +# Normally used with prefix = '/' after a chdir(). +# +def forget_except_prefix(prefix): + n = len(prefix) + for path in cache.keys(): + if path[:n] <> prefix: + del cache[path] + + +# Check for directory. +# +def isdir(path): + try: + # mode is st[0]; type is mode/4096; S_IFDIR is 4 + return stat(path)[0] / 4096 = 4 + except RuntimeError: + return 0 diff --git a/Lib/stdwin/anywin.py b/Lib/stdwin/anywin.py new file mode 100755 index 00000000000..bb7e86547b8 --- /dev/null +++ b/Lib/stdwin/anywin.py @@ -0,0 +1,14 @@ +# Module 'anywin' +# Open a file or directory in a window + +import dirwin +import filewin +import path + +def open(name): + print 'opening', name, '...' + if path.isdir(name): + w = dirwin.open(name) + else: + w = filewin.open(name) + return w diff --git a/Lib/stdwin/dirwin.py b/Lib/stdwin/dirwin.py new file mode 100755 index 00000000000..5df85e7e39f --- /dev/null +++ b/Lib/stdwin/dirwin.py @@ -0,0 +1,28 @@ +# Module 'dirwin' + +# Directory windows, a subclass of listwin + +import gwin +import listwin +import anywin +import path +import dircache + +def action(w, string, i, detail): + (h, v), clicks, button, mask = detail + if clicks = 2: + name = path.cat(w.name, string) + try: + w = anywin.open(name) + except posix.error, why: + stdwin.message('Can\'t open ' + name + ': ' + why[1]) + +def open(name): + name = path.cat(name, '') + list = dircache.opendir(name)[:] + list.sort() + dircache.annotate(name, list) + w = listwin.open(name, list) + w.name = name + w.action = action + return w diff --git a/Lib/stdwin/filewin.py b/Lib/stdwin/filewin.py new file mode 100755 index 00000000000..1beb0b6520c --- /dev/null +++ b/Lib/stdwin/filewin.py @@ -0,0 +1,31 @@ +# Module 'filewin' +# File windows, a subclass of textwin (which is a subclass of gwin) + +import stdwin +import textwin +import path + +builtin_open = open + +def readfile(fn): # Return a string containing the file's contents + fp = builtin_open(fn, 'r') + a = '' + n = 8096 + while 1: + b = fp.read(n) + if not b: break + a = a + b + return a + + +# FILE WINDOW + +def open_readonly(fn): # Open a file window + w = textwin.open_readonly(fn, readfile(fn)) + w.fn = fn + return w + +def open(fn): # Open a file window + w = textwin.open(fn, readfile(fn)) + w.fn = fn + return w diff --git a/Lib/stdwin/gwin.py b/Lib/stdwin/gwin.py new file mode 100755 index 00000000000..15aa4327ce5 --- /dev/null +++ b/Lib/stdwin/gwin.py @@ -0,0 +1,118 @@ +# Module 'gwin' +# Generic stdwin windows + +# This is used as a base class from which to derive other window types. +# The mainloop() function here is an event dispatcher for all window types. + +import stdwin +import stdwinsupport + +S = stdwinsupport # Shorthand + +windows = [] # List of open windows + + +# Open a window + +def open(title): # Open a generic window + w = stdwin.open(title) + stdwin.setdefwinsize(0, 0) + # Set default event handlers + w.draw = nop + w.char = nop + w.mdown = nop + w.mmove = nop + w.mup = nop + w.m2down = m2down + w.m2up = m2up + w.size = nop + w.move = nop + w.activate = w.deactivate = nop + w.timer = nop + # default command handlers + w.close = close + w.tab = tab + w.enter = enter + w.backspace = backspace + w.arrow = arrow + w.kleft = w.kup = w.kright = w.kdown = nop + windows.append(w) + return w + + +# Generic event dispatching + +def mainloop(): # Handle events until no windows left + while windows: + treatevent(stdwin.getevent()) + +def treatevent(e): # Handle a stdwin event + type, w, detail = e + if type = S.we_draw: + w.draw(w, detail) + elif type = S.we_menu: + m, item = detail + m.action[item](w, m, item) + elif type = S.we_command: + treatcommand(w, detail) + elif type = S.we_char: + w.char(w, detail) + elif type = S.we_mouse_down: + if detail[1] > 1: w.m2down(w, detail) + else: w.mdown(w, detail) + elif type = S.we_mouse_move: + w.mmove(w, detail) + elif type = S.we_mouse_up: + if detail[1] > 1: w.m2up(w, detail) + else: w.mup(w, detail) + elif type = S.we_size: + w.size(w, w.getwinsize()) + elif type = S.we_activate: + w.activate(w) + elif type = S.we_deactivate: + w.deactivate(w) + elif type = S.we_move: + w.move(w) + elif type = S.we_timer: + w.timer(w) + +def treatcommand(w, type): # Handle a we_command event + if type = S.wc_close: + w.close(w) + elif type = S.wc_return: + w.enter(w) + elif type = S.wc_tab: + w.tab(w) + elif type = S.wc_backspace: + w.backspace(w) + elif type in (S.wc_left, S.wc_up, S.wc_right, S.wc_down): + w.arrow(w, type) + + +# Methods + +def close(w): # Close method + for i in range(len(windows)): + if windows[i] is w: + del windows[i] + break + +def arrow(w, detail): # Arrow key method + if detail = S.wc_left: + w.kleft(w) + elif detail = S.wc_up: + w.kup(w) + elif detail = S.wc_right: + w.kright(w) + elif detail = S.wc_down: + w.kdown(w) + + +# Trivial methods + +def tab(w): w.char(w, '\t') +def enter(w): w.char(w, '\n') # 'return' is a Python reserved word +def backspace(w): w.char(w, '\b') +def m2down(w, detail): w.mdown(w, detail) +def m2up(w, detail): w.mup(w, detail) +def nop(args): pass diff --git a/Lib/stdwin/listwin.py b/Lib/stdwin/listwin.py new file mode 100755 index 00000000000..9480a81fc9c --- /dev/null +++ b/Lib/stdwin/listwin.py @@ -0,0 +1,47 @@ +# Module 'listwin' +# List windows, a subclass of gwin + +import gwin +import stdwin + +def maxlinewidth(a): # Compute maximum textwidth of lines in a sequence + max = 0 + for line in a: + width = stdwin.textwidth(line) + if width > max: max = width + return max + +def action(w, string, i, detail): # Default item selection method + pass + +def mup(w, detail): # Mouse up method + (h, v), clicks, button, mask = detail + i = divmod(v, w.lineheight)[0] + if 0 <= i < len(w.data): + w.action(w, w.data[i], i, detail) + +def draw(w, ((left, top), (right, bottom))): # Text window draw method + data = w.data + d = w.begindrawing() + lh = w.lineheight + itop = top/lh + ibot = (bottom-1)/lh + 1 + if itop < 0: itop = 0 + if ibot > len(data): ibot = len(data) + for i in range(itop, ibot): d.text((0, i*lh), data[i]) + +def open(title, data): # Display a list of texts in a window + lineheight = stdwin.lineheight() + h, v = maxlinewidth(data), len(data)*lineheight + h0, v0 = h + stdwin.textwidth(' '), v + lineheight + if h0 > stdwin.textwidth(' ')*80: h0 = 0 + if v0 > stdwin.lineheight()*24: v0 = 0 + stdwin.setdefwinsize(h0, v0) + w = gwin.open(title) + w.setdocsize(h, v) + w.lineheight = lineheight + w.data = data + w.draw = draw + w.action = action + w.mup = mup + return w diff --git a/Lib/stdwin/rect.py b/Lib/stdwin/rect.py new file mode 100755 index 00000000000..c044b9f0c71 --- /dev/null +++ b/Lib/stdwin/rect.py @@ -0,0 +1,87 @@ +# Module 'rect'. +# +# Operations on rectangles. +# There is some normalization: all results return the object 'empty' +# if their result would contain no points. + + +# Exception. +# +error = 'rect.error' + + +# The empty rectangle. +# +empty = (0, 0), (0, 0) + + +# Check if a rectangle is empty. +# +def is_empty((left, top), (right, bottom)): + return left >= right or top >= bottom + + +# Compute the intersection or two or more rectangles. +# This works with a list or tuple argument. +# +def intersect(list): + if not list: raise error, 'intersect called with empty list' + if is_empty(list[0]): return empty + (left, top), (right, bottom) = list[0] + for rect in list[1:]: + if not is_empty(rect): + (l, t), (r, b) = rect + if left < l: left = l + if top < t: top = t + if right > r: right = r + if bottom > b: bottom = b + if is_empty((left, top), (right, bottom)): + return empty + return (left, top), (right, bottom) + + +# Compute the smallest rectangle containing all given rectangles. +# This works with a list or tuple argument. +# +def union(list): + (left, top), (right, bottom) = empty + for (l, t), (r, b) in list[1:]: + if not is_empty((l, t), (r, b)): + if l < left: left = l + if t < top: top = t + if r > right: right = r + if b > bottom: bottom = b + res = (left, top), (right, bottom) + if is_empty(res): + return empty + return res + + +# Check if a point is in a rectangle. +# +def pointinrect((h, v), ((left, top), (right, bottom))): + return left <= h < right and top <= v < bottom + + +# Return a rectangle that is dh, dv inside another +# +def inset(((left, top), (right, bottom)), (dh, dv)): + left = left + dh + top = top + dv + right = right - dh + bottom = bottom - dv + r = (left, top), (right, bottom) + if is_empty(r): + return empty + else: + return r + + +# Conversions between rectangles and 'geometry tuples', +# given as origin (h, v) and dimensions (width, height). +# +def rect2geom((left, top), (right, bottom)): + return (left, top), (right-left, bottom-top) + +def geom2rect((h, v), (width, height)): + return (h, v), (h+width, v+height) diff --git a/Lib/stdwin/stdwinevents.py b/Lib/stdwin/stdwinevents.py new file mode 100755 index 00000000000..889dd959829 --- /dev/null +++ b/Lib/stdwin/stdwinevents.py @@ -0,0 +1,36 @@ +# Module 'stdwinevents' -- Constants for stdwin event types +# +# Suggested usage: +# from stdwinevents import * + +# The function stdwin.getevent() returns a tuple containing: +# (type, window, detail) +# where detail may be or a value depending on type, see below: + +# Values for type: + +WE_NULL = 0 # not reported -- means 'no event' internally +WE_ACTIVATE = 1 # detail is +WE_CHAR = 2 # detail is the character +WE_COMMAND = 3 # detail is one of the WC_* constants below +WE_MOUSE_DOWN = 4 # detail is ((h, v), clicks, button, mask) +WE_MOUSE_MOVE = 5 # ditto +WE_MOUSE_UP = 6 # ditto +WE_MENU = 7 # detail is (menu, item) +WE_SIZE = 8 # detail is (width, height) [???] +WE_MOVE = 9 # not reported -- reserved for future use +WE_DRAW = 10 # detail is ((left, top), (right, bottom)) +WE_TIMER = 11 # detail is +WE_DEACTIVATE = 12 # detail is + +# Values for detail when type is WE_COMMAND: + +WC_CLOSE = 1 # user hit close box +WC_LEFT = 2 # left arrow key +WC_RIGHT = 3 # right arrow key +WC_UP = 4 # up arrow key +WC_DOWN = 5 # down arrow key +WC_CANCEL = 6 # not reported -- turned into KeyboardInterrupt +WC_BACKSPACE = 7 # backspace key +WC_TAB = 8 # tab key +WC_RETURN = 9 # return or enter key diff --git a/Lib/stdwin/tablewin.py b/Lib/stdwin/tablewin.py new file mode 100755 index 00000000000..05a954e5b86 --- /dev/null +++ b/Lib/stdwin/tablewin.py @@ -0,0 +1,237 @@ +# Module 'tablewin' + +# Display a table, with per-item actions: + +# A1 | A2 | A3 | .... | AN +# B1 | B2 | B3 | .... | BN +# C1 | C2 | C3 | .... | CN +# .. | .. | .. | .... | .. +# Z1 | Z2 | Z3 | .... | ZN + +# Not all columns need to have the same length. +# The data structure is a list of columns; +# each column is a list of items. +# Each item is a pair of a string and an action procedure. +# The first item may be a column title. + +import stdwin +import gwin + +def open(title, data): # Public function to open a table window + # + # Set geometry parameters (one day, these may be changeable) + # + margin = stdwin.textwidth(' ') + lineheight = stdwin.lineheight() + # + # Geometry calculations + # + colstarts = [0] + totwidth = 0 + maxrows = 0 + for coldata in data: + # Height calculations + rows = len(coldata) + if rows > maxrows: maxrows = rows + # Width calculations + width = colwidth(coldata) + margin + totwidth = totwidth + width + colstarts.append(totwidth) + # + # Calculate document and window height + # + docwidth, docheight = totwidth, maxrows*lineheight + winwidth, winheight = docwidth, docheight + if winwidth > stdwin.textwidth('n')*100: winwidth = 0 + if winheight > stdwin.lineheight()*30: winheight = 0 + # + # Create the window + # + stdwin.setdefwinsize(winwidth, winheight) + w = gwin.open(title) + # + # Set properties and override methods + # + w.data = data + w.margin = margin + w.lineheight = lineheight + w.colstarts = colstarts + w.totwidth = totwidth + w.maxrows = maxrows + w.selection = (-1, -1) + w.lastselection = (-1, -1) + w.selshown = 0 + w.setdocsize(docwidth, docheight) + w.draw = draw + w.mup = mup + w.arrow = arrow + # + # Return + # + return w + +def update(w, data): # Change the data + # + # Hide selection + # + hidesel(w, w.begindrawing()) + # + # Get old geometry parameters + # + margin = w.margin + lineheight = w.lineheight + # + # Geometry calculations + # + colstarts = [0] + totwidth = 0 + maxrows = 0 + for coldata in data: + # Height calculations + rows = len(coldata) + if rows > maxrows: maxrows = rows + # Width calculations + width = colwidth(coldata) + margin + totwidth = totwidth + width + colstarts.append(totwidth) + # + # Calculate document and window height + # + docwidth, docheight = totwidth, maxrows*lineheight + # + # Set changed properties and change window size + # + w.data = data + w.colstarts = colstarts + w.totwidth = totwidth + w.maxrows = maxrows + w.change((0, 0), (10000, 10000)) + w.setdocsize(docwidth, docheight) + w.change((0, 0), (docwidth, docheight)) + # + # Show selection, or forget it if out of range + # + showsel(w, w.begindrawing()) + if not w.selshown: w.selection = (-1, -1) + +def colwidth(coldata): # Subroutine to calculate column width + maxwidth = 0 + for string, action in coldata: + width = stdwin.textwidth(string) + if width > maxwidth: maxwidth = width + return maxwidth + +def draw(w, ((left, top), (right, bottom))): # Draw method + ileft = whichcol(w, left) + iright = whichcol(w, right-1) + 1 + if iright > len(w.data): iright = len(w.data) + itop = divmod(top, w.lineheight)[0] + if itop < 0: itop = 0 + ibottom, remainder = divmod(bottom, w.lineheight) + if remainder: ibottom = ibottom + 1 + d = w.begindrawing() + if ileft <= w.selection[0] < iright: + if itop <= w.selection[1] < ibottom: + hidesel(w, d) + d.erase((left, top), (right, bottom)) + for i in range(ileft, iright): + col = w.data[i] + jbottom = len(col) + if ibottom < jbottom: jbottom = ibottom + h = w.colstarts[i] + v = itop * w.lineheight + for j in range(itop, jbottom): + string, action = col[j] + d.text((h, v), string) + v = v + w.lineheight + showsel(w, d) + +def mup(w, detail): # Mouse up method + (h, v), nclicks, button, mask = detail + icol = whichcol(w, h) + if 0 <= icol < len(w.data): + irow = divmod(v, w.lineheight)[0] + col = w.data[icol] + if 0 <= irow < len(col): + string, action = col[irow] + action(w, string, (icol, irow), detail) + +def whichcol(w, h): # Return column number (may be >= len(w.data)) + for icol in range(0, len(w.data)): + if h < w.colstarts[icol+1]: + return icol + return len(w.data) + +def arrow(w, type): + import stdwinsupport + S = stdwinsupport + if type = S.wc_left: + incr = -1, 0 + elif type = S.wc_up: + incr = 0, -1 + elif type = S.wc_right: + incr = 1, 0 + elif type = S.wc_down: + incr = 0, 1 + else: + return + icol, irow = w.lastselection + icol = icol + incr[0] + if icol < 0: icol = len(w.data)-1 + if icol >= len(w.data): icol = 0 + if 0 <= icol < len(w.data): + irow = irow + incr[1] + if irow < 0: irow = len(w.data[icol]) - 1 + if irow >= len(w.data[icol]): irow = 0 + else: + irow = 0 + if 0 <= icol < len(w.data) and 0 <= irow < len(w.data[icol]): + w.lastselection = icol, irow + string, action = w.data[icol][irow] + detail = (0, 0), 1, 1, 1 + action(w, string, (icol, irow), detail) + + +# Selection management +# TO DO: allow multiple selected entries + +def select(w, selection): # Public function to set the item selection + d = w.begindrawing() + hidesel(w, d) + w.selection = selection + showsel(w, d) + if w.selshown: lastselection = selection + +def hidesel(w, d): # Hide the selection, if shown + if w.selshown: invertsel(w, d) + +def showsel(w, d): # Show the selection, if hidden + if not w.selshown: invertsel(w, d) + +def invertsel(w, d): # Invert the selection, if valid + icol, irow = w.selection + if 0 <= icol < len(w.data) and 0 <= irow < len(w.data[icol]): + left = w.colstarts[icol] + right = w.colstarts[icol+1] + top = irow * w.lineheight + bottom = (irow+1) * w.lineheight + d.invert((left, top), (right, bottom)) + w.selshown = (not w.selshown) + + +# Demonstration + +def demo_action(w, string, (icol, irow), detail): # Action function for demo + select(w, (irow, icol)) + +def demo(): # Demonstration + da = demo_action # shorthand + col0 = [('a1', da), ('bbb1', da), ('c1', da)] + col1 = [('a2', da), ('bbb2', da)] + col2 = [('a3', da), ('b3', da), ('c3', da), ('d4', da), ('d5', da)] + col3 = [] + for i in range(1, 31): col3.append('xxx' + `i`, da) + data = [col0, col1, col2, col3] + w = open('tablewin.demo', data) + gwin.mainloop() + return w diff --git a/Lib/stdwin/textwin.py b/Lib/stdwin/textwin.py new file mode 100755 index 00000000000..2631ca4ee54 --- /dev/null +++ b/Lib/stdwin/textwin.py @@ -0,0 +1,119 @@ +# Module 'textwin' + +# Text windows, a subclass of gwin + +import stdwin +import stdwinsupport +import gwin + +S = stdwinsupport # Shorthand + + +def fixsize(w): + docwidth, docheight = w.text.getrect()[1] + winheight = w.getwinsize()[1] + if winheight > docheight: docheight = winheight + w.setdocsize(0, docheight) + fixeditmenu(w) + +def cut(w, m, id): + s = w.text.getfocustext() + if s: + stdwin.setcutbuffer(s) + w.text.replace('') + fixsize(w) + +def copy(w, m, id): + s = w.text.getfocustext() + if s: + stdwin.setcutbuffer(s) + fixeditmenu(w) + +def paste(w, m, id): + w.text.replace(stdwin.getcutbuffer()) + fixsize(w) + +def addeditmenu(w): + m = w.editmenu = w.menucreate('Edit') + m.action = [] + m.additem('Cut', 'X') + m.action.append(cut) + m.additem('Copy', 'C') + m.action.append(copy) + m.additem('Paste', 'V') + m.action.append(paste) + +def fixeditmenu(w): + m = w.editmenu + f = w.text.getfocus() + can_copy = (f[0] < f[1]) + m.enable(1, can_copy) + if not w.readonly: + m.enable(0, can_copy) + m.enable(2, (stdwin.getcutbuffer() <> '')) + +def draw(w, area): # Draw method + w.text.draw(area) + +def size(w, newsize): # Size method + w.text.move((0, 0), newsize) + fixsize(w) + +def close(w): # Close method + del w.text # Break circular ref + gwin.close(w) + +def char(w, c): # Char method + w.text.replace(c) + fixsize(w) + +def backspace(w): # Backspace method + void = w.text.event(S.we_command, w, S.wc_backspace) + fixsize(w) + +def arrow(w, detail): # Arrow method + w.text.arrow(detail) + fixeditmenu(w) + +def mdown(w, detail): # Mouse down method + void = w.text.event(S.we_mouse_down, w, detail) + fixeditmenu(w) + +def mmove(w, detail): # Mouse move method + void = w.text.event(S.we_mouse_move, w, detail) + +def mup(w, detail): # Mouse up method + void = w.text.event(S.we_mouse_up, w, detail) + fixeditmenu(w) + +def activate(w): # Activate method + fixeditmenu(w) + +def open(title, str): # Display a string in a window + w = gwin.open(title) + w.readonly = 0 + w.text = w.textcreate((0, 0), w.getwinsize()) + w.text.replace(str) + w.text.setfocus(0, 0) + addeditmenu(w) + fixsize(w) + w.draw = draw + w.size = size + w.close = close + w.mdown = mdown + w.mmove = mmove + w.mup = mup + w.char = char + w.backspace = backspace + w.arrow = arrow + w.activate = activate + return w + +def open_readonly(title, str): # Same with char input disabled + w = open(title, str) + w.readonly = 1 + w.char = w.backspace = gwin.nop + # Disable Cut and Paste menu item; leave Copy alone + w.editmenu.enable(0, 0) + w.editmenu.enable(2, 0) + return w diff --git a/Lib/string.py b/Lib/string.py new file mode 100644 index 00000000000..2a4feaebcc0 --- /dev/null +++ b/Lib/string.py @@ -0,0 +1,129 @@ +# module 'string' -- A collection of string operations + +# XXX Some of these operations are incredibly slow and should be built in + +# Some strings for ctype-style character classification +whitespace = ' \t\n' +lowercase = 'abcdefghijklmnopqrstuvwxyz' +uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +letters = lowercase + uppercase +digits = '0123456789' +hexdigits = digits + 'abcdef' + 'ABCDEF' +octdigits = '01234567' + +# Case conversion helpers +_caseswap = {} +for i in range(26): + _caseswap[lowercase[i]] = uppercase[i] + _caseswap[uppercase[i]] = lowercase[i] +del i + +# convert UPPER CASE letters to lower case +def lower(s): + res = '' + for c in s: + if 'A' <= c <= 'Z': c = _caseswap[c] + res = res + c + return res + +# Convert lower case letters to UPPER CASE +def upper(s): + res = '' + for c in s: + if 'a' <= c <= 'z': c = _caseswap[c] + res = res + c + return res + +# Swap lower case letters and UPPER CASE +def swapcase(s): + res = '' + for c in s: + if 'a' <= c <= 'z' or 'A' <= c <= 'Z': c = _caseswap[c] + res = res + c + return res + +# Strip leading and trailing tabs and spaces +def strip(s): + i, j = 0, len(s) + while i < j and s[i] in whitespace: i = i+1 + while i < j and s[j-1] in whitespace: j = j-1 + return s[i:j] + +# Split a string into a list of space/tab-separated words +# NB: split(s) is NOT the same as splitfields(s, ' ')! +def split(s): + res = [] + i, n = 0, len(s) + while i < n: + while i < n and s[i] in whitespace: i = i+1 + if i = n: break + j = i + while j < n and s[j] not in whitespace: j = j+1 + res.append(s[i:j]) + i = j + return res + +# Split a list into fields separated by a given string +# NB: splitfields(s, ' ') is NOT the same as split(s)! +def splitfields(s, sep): + res = [] + ns = len(s) + nsep = len(sep) + i = j = 0 + while j+nsep <= ns: + if s[j:j+nsep] = sep: + res.append(s[i:j]) + i = j = j + nsep + else: + j = j + 1 + res.append(s[i:]) + return res + +# Find substring +index_error = 'substring not found in string.index' +def index(s, sub): + n = len(sub) + for i in range(len(s) - n): + if sub = s[i:i+n]: return i + raise index_error, (s, sub) + +# Convert string to integer +atoi_error = 'non-numeric argument to string.atoi' +def atoi(str): + s = str + if s[:1] in '+-': s = s[1:] + if not s: raise atoi_error, str + for c in s: + if c not in digits: raise atoi_error, str + return eval(str) + +# Left-justify a string +def ljust(s, width): + n = len(s) + if n >= width: return s + return s + ' '*(width-n) + +# Right-justify a string +def rjust(s, width): + n = len(s) + if n >= width: return s + return ' '*(width-n) + s + +# Center a string +def center(s, width): + n = len(s) + if n >= width: return s + return ' '*((width-n)/2) + s + ' '*(width -(width-n)/2) + +# Zero-fill a number, e.g., (12, 3) --> '012' and (-3, 3) --> '-03' +# Decadent feature: the argument may be a string or a number +# (Use of this is deprecated; it should be a string as with ljust c.s.) +def zfill(x, width): + if type(x) = type(''): s = x + else: s = `x` + n = len(s) + if n >= width: return s + sign = '' + if s[0] = '-': + sign, s = '-', s[1:] + return sign + '0'*(width-n) + s diff --git a/Lib/stringold.py b/Lib/stringold.py new file mode 100644 index 00000000000..2a4feaebcc0 --- /dev/null +++ b/Lib/stringold.py @@ -0,0 +1,129 @@ +# module 'string' -- A collection of string operations + +# XXX Some of these operations are incredibly slow and should be built in + +# Some strings for ctype-style character classification +whitespace = ' \t\n' +lowercase = 'abcdefghijklmnopqrstuvwxyz' +uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +letters = lowercase + uppercase +digits = '0123456789' +hexdigits = digits + 'abcdef' + 'ABCDEF' +octdigits = '01234567' + +# Case conversion helpers +_caseswap = {} +for i in range(26): + _caseswap[lowercase[i]] = uppercase[i] + _caseswap[uppercase[i]] = lowercase[i] +del i + +# convert UPPER CASE letters to lower case +def lower(s): + res = '' + for c in s: + if 'A' <= c <= 'Z': c = _caseswap[c] + res = res + c + return res + +# Convert lower case letters to UPPER CASE +def upper(s): + res = '' + for c in s: + if 'a' <= c <= 'z': c = _caseswap[c] + res = res + c + return res + +# Swap lower case letters and UPPER CASE +def swapcase(s): + res = '' + for c in s: + if 'a' <= c <= 'z' or 'A' <= c <= 'Z': c = _caseswap[c] + res = res + c + return res + +# Strip leading and trailing tabs and spaces +def strip(s): + i, j = 0, len(s) + while i < j and s[i] in whitespace: i = i+1 + while i < j and s[j-1] in whitespace: j = j-1 + return s[i:j] + +# Split a string into a list of space/tab-separated words +# NB: split(s) is NOT the same as splitfields(s, ' ')! +def split(s): + res = [] + i, n = 0, len(s) + while i < n: + while i < n and s[i] in whitespace: i = i+1 + if i = n: break + j = i + while j < n and s[j] not in whitespace: j = j+1 + res.append(s[i:j]) + i = j + return res + +# Split a list into fields separated by a given string +# NB: splitfields(s, ' ') is NOT the same as split(s)! +def splitfields(s, sep): + res = [] + ns = len(s) + nsep = len(sep) + i = j = 0 + while j+nsep <= ns: + if s[j:j+nsep] = sep: + res.append(s[i:j]) + i = j = j + nsep + else: + j = j + 1 + res.append(s[i:]) + return res + +# Find substring +index_error = 'substring not found in string.index' +def index(s, sub): + n = len(sub) + for i in range(len(s) - n): + if sub = s[i:i+n]: return i + raise index_error, (s, sub) + +# Convert string to integer +atoi_error = 'non-numeric argument to string.atoi' +def atoi(str): + s = str + if s[:1] in '+-': s = s[1:] + if not s: raise atoi_error, str + for c in s: + if c not in digits: raise atoi_error, str + return eval(str) + +# Left-justify a string +def ljust(s, width): + n = len(s) + if n >= width: return s + return s + ' '*(width-n) + +# Right-justify a string +def rjust(s, width): + n = len(s) + if n >= width: return s + return ' '*(width-n) + s + +# Center a string +def center(s, width): + n = len(s) + if n >= width: return s + return ' '*((width-n)/2) + s + ' '*(width -(width-n)/2) + +# Zero-fill a number, e.g., (12, 3) --> '012' and (-3, 3) --> '-03' +# Decadent feature: the argument may be a string or a number +# (Use of this is deprecated; it should be a string as with ljust c.s.) +def zfill(x, width): + if type(x) = type(''): s = x + else: s = `x` + n = len(s) + if n >= width: return s + sign = '' + if s[0] = '-': + sign, s = '-', s[1:] + return sign + '0'*(width-n) + s diff --git a/Lib/util.py b/Lib/util.py new file mode 100644 index 00000000000..dc67686a327 --- /dev/null +++ b/Lib/util.py @@ -0,0 +1,9 @@ +# Module 'util' -- some useful functions that dont fit elsewhere + +# Remove an item from a list at most once +# +def remove(item, list): + for i in range(len(list)): + if list[i] = item: + del list[i] + break diff --git a/Lib/whrandom.py b/Lib/whrandom.py new file mode 100644 index 00000000000..2ce5f8f79ad --- /dev/null +++ b/Lib/whrandom.py @@ -0,0 +1,74 @@ +# WICHMANN-HILL RANDOM NUMBER GENERATOR +# +# Wichmann, B. A. & Hill, I. D. (1982) +# Algorithm AS 183: +# An efficient and portable pseudo-random number generator +# Applied Statistics 31 (1982) 188-190 +# +# see also: +# Correction to Algorithm AS 183 +# Applied Statistics 33 (1984) 123 +# +# McLeod, A. I. (1985) +# A remark on Algorithm AS 183 +# Applied Statistics 34 (1985),198-200 +# +# +# USE: +# whrandom.random() yields double precision random numbers +# uniformly distributed between 0 and 1. +# +# whrandom.seed() must be called before whrandom.random() +# to seed the generator + + +# 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 + # + [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) + # + if x < 0: x = x + 30269 + if y < 0: y = y + 30307 + if z < 0: z = z + 30323 + # + _seed[:] = [x, y, z] + # + term = float(x)/30269.0 + float(y)/30307.0 + float(z)/30323.0 + rand = term - floor(term) + # + if rand >= 1.0: rand = 0.0 # floor() inaccuracy? + # + return rand + + +# 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()