From 07c9645413543acbf6dff349c02e3be2bf2bc5a4 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 3 Oct 1994 16:45:35 +0000 Subject: Get rid of freeze (now its own directory). Added some new demos. Fixed a few others. --- Demo/scripts/README | 4 +- Demo/scripts/morse.py | 149 ++++++++++++++++++++++++++++++++++++++++++++++++ Demo/scripts/script.py | 33 +++++++++++ Tools/scripts/fixcid.py | 7 ++- Tools/scripts/h2py.py | 80 +++++++++++++++++++------- Tools/scripts/sum5.py | 97 +++++++++++++++++++++++++++++++ 6 files changed, 345 insertions(+), 25 deletions(-) create mode 100755 Demo/scripts/morse.py create mode 100755 Demo/scripts/script.py create mode 100755 Tools/scripts/sum5.py diff --git a/Demo/scripts/README b/Demo/scripts/README index 5b5e88d..e7443da 100644 --- a/Demo/scripts/README +++ b/Demo/scripts/README @@ -21,7 +21,6 @@ findlinksto.py Recursively find symbolic links to a given path prefix fixps.py Fix Python scripts' first line (if #!) fixcid.py Massive identifier substitution on C source files fixheader.py Add some cpp magic to a C include file -freeze.py Convert a Python script into a free-standing binary from.py Summarize mailbox ftpstats.py Summarize ftp daemon log file ifdef.py Remove #if(n)def groups from C sources @@ -31,6 +30,7 @@ lpwatch.py Watch BSD line printer queues markov.py Markov chain simulation of words or characters mboxconvvert.py Convert MH or MMDF mailboxes to unix mailbox format methfix.py Fix old method syntax def f(self, (a1, ..., aN)): +morse.py Produce morse code (audible or on AIFF file) mkreal.py Turn a symbolic link into a real file or directory mpzpi.py test mpz -- print digits of pi (compare pi.py) objgraph.py Print object graph from nm output on a library @@ -41,7 +41,9 @@ pindent.py Indent Python code, giving block-closing comments pp.py Emulate some Perl command line options primes.py Print prime numbers ptags.py Create vi tags file for Python modules +script.py Equivalent to BSD script(1) -- by Steen Lumholt suff.py Sort a list of files by suffix +sum5.py Print md5 checksums of files unbirthday.py Print unbirthday count which.py Find a program in $PATH xxci.py Wrapper for rcsdiff and ci diff --git a/Demo/scripts/morse.py b/Demo/scripts/morse.py new file mode 100755 index 0000000..2cea83e --- /dev/null +++ b/Demo/scripts/morse.py @@ -0,0 +1,149 @@ +# DAH should be three DOTs. +# Space between DOTs and DAHs should be one DOT. +# Space between two letters should be one DAH. +# Space between two words should be DOT DAH DAH. + +import sys, math, audiodev + +DOT = 30 +DAH = 3 * DOT +OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ... + +morsetab = { + 'A': '.-', 'a': '.-', + 'B': '-...', 'b': '-...', + 'C': '-.-.', 'c': '-.-.', + 'D': '-..', 'd': '-..', + 'E': '.', 'e': '.', + 'F': '..-.', 'f': '..-.', + 'G': '--.', 'g': '--.', + 'H': '....', 'h': '....', + 'I': '..', 'i': '..', + 'J': '.---', 'j': '.---', + 'K': '-.-', 'k': '-.-', + 'L': '.-..', 'l': '.-..', + 'M': '--', 'm': '--', + 'N': '-.', 'n': '-.', + 'O': '---', 'o': '---', + 'P': '.--.', 'p': '.--.', + 'Q': '--.-', 'q': '--.-', + 'R': '.-.', 'r': '.-.', + 'S': '...', 's': '...', + 'T': '-', 't': '-', + 'U': '..-', 'u': '..-', + 'V': '...-', 'v': '...-', + 'W': '.--', 'w': '.--', + 'X': '-..-', 'x': '-..-', + 'Y': '-.--', 'y': '-.--', + 'Z': '--..', 'z': '--..', + '0': '-----', + '1': '.----', + '2': '..---', + '3': '...--', + '4': '....-', + '5': '.....', + '6': '-....', + '7': '--...', + '8': '---..', + '9': '----.', + ',': '--..--', + '.': '.-.-.-', + '?': '..--..', + ';': '-.-.-.', + ':': '---...', + "'": '.----.', + '-': '-....-', + '/': '-..-.', + '(': '-.--.-', + ')': '-.--.-', + '_': '..--.-', + ' ': ' ' +} + +# If we play at 44.1 kHz (which we do), then if we produce one sine +# wave in 100 samples, we get a tone of 441 Hz. If we produce two +# sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz +# appears to be a nice one for playing morse code. +def mkwave(octave): + global sinewave, nowave + sinewave = '' + for i in range(100): + val = int(math.sin(math.pi * float(i) * octave / 50.0) * 30000) + sinewave = sinewave + chr((val >> 8) & 255) + chr(val & 255) + nowave = '\0' * 200 + +mkwave(OCTAVE) + +def main(): + import getopt, string + try: + opts, args = getopt.getopt(sys.argv[1:], 'o:p:') + except getopt.error: + sys.stderr.write('Usage ' + sys.argv[0] + + ' [ -o outfile ] [ args ] ...\n') + sys.exit(1) + dev = None + for o, a in opts: + if o == '-o': + import aifc + dev = aifc.open(a, 'w') + dev.setframerate(44100) + dev.setsampwidth(2) + dev.setnchannels(1) + if o == '-p': + mkwave(string.atoi(a)) + if not dev: + import audiodev + dev = audiodev.AudioDev() + dev.setoutrate(44100) + dev.setsampwidth(2) + dev.setnchannels(1) + dev.close = dev.stop + dev.writeframesraw = dev.writeframes + if args: + line = string.join(args) + else: + line = sys.stdin.readline() + while line: + mline = morse(line) + play(mline, dev) + if hasattr(dev, 'wait'): + dev.wait() + if not args: + line = sys.stdin.readline() + else: + line = '' + dev.close() + +# Convert a string to morse code with \001 between the characters in +# the string. +def morse(line): + res = '' + for c in line: + try: + res = res + morsetab[c] + '\001' + except KeyError: + pass + return res + +# Play a line of morse code. +def play(line, dev): + for c in line: + if c == '.': + sine(dev, DOT) + elif c == '-': + sine(dev, DAH) + else: # space + pause(dev, DAH + DOT) + pause(dev, DOT) + +def sine(dev, length): + for i in range(length): + dev.writeframesraw(sinewave) + +def pause(dev, length): + for i in range(length): + dev.writeframesraw(nowave) + +if __name__ == '__main__' or sys.argv[0] == __name__: + main() diff --git a/Demo/scripts/script.py b/Demo/scripts/script.py new file mode 100755 index 0000000..04e7ecb --- /dev/null +++ b/Demo/scripts/script.py @@ -0,0 +1,33 @@ +#! /usr/local/bin/python +# script.py -- Make typescript of terminal session. +# Usage: +# -a Append to typescript. +# -p Use Python as shell. +# Author: Steen Lumholt. + + +import os, time, sys +import pty + +def read(fd): + data = os.read(fd, 1024) + file.write(data) + return data + +shell = 'sh' +filename = 'typescript' +mode = 'w' +if os.environ.has_key('SHELL'): + shell = os.environ['SHELL'] +if '-a' in sys.argv: + mode = 'a' +if '-p' in sys.argv: + shell = 'python' + +file = open(filename, mode) + +sys.stdout.write('Script started, file is %s\n' % filename) +file.write('Script started on %s\n' % time.ctime(time.time())) +pty.spawn(shell, read) +file.write('Script done on %s\n' % time.ctime(time.time())) +sys.stdout.write('Script done, file is %s\n' % filename) diff --git a/Tools/scripts/fixcid.py b/Tools/scripts/fixcid.py index ce3f1f3..3b37bb8 100755 --- a/Tools/scripts/fixcid.py +++ b/Tools/scripts/fixcid.py @@ -194,7 +194,7 @@ def fix(filename): # Tokenizing ANSI C (partly) -Identifier = '[a-zA-Z_][a-zA-Z0-9_]+' +Identifier = '\(struct \)?[a-zA-Z_][a-zA-Z0-9_]+' String = '"\([^\n\\"]\|\\\\.\)*"' Char = '\'\([^\n\\\']\|\\\\.\)*\'' CommentStart = '/\*' @@ -246,6 +246,7 @@ def fixline(line): if Program is InsideCommentProgram: if not Docomments: print 'Found in comment:', found + i = i + n continue if NotInComment.has_key(found): ## print 'Ignored in comment:', @@ -290,7 +291,9 @@ def addsubst(substfile): i = -1 # Happens to delete trailing \n words = string.split(line[:i]) if not words: continue - if len(words) <> 2: + if len(words) == 3 and words[0] == 'struct': + words[:2] == [words[0] + ' ' + words[1]] + elif len(words) <> 2: err(substfile + ':' + `lineno` + ': warning: bad line: ' + line) continue diff --git a/Tools/scripts/h2py.py b/Tools/scripts/h2py.py index 3d7a851..db0dbd8 100755 --- a/Tools/scripts/h2py.py +++ b/Tools/scripts/h2py.py @@ -1,32 +1,43 @@ #! /usr/local/bin/python -# Read #define's from stdin and translate to Python code on stdout. -# Very primitive: non-#define's are ignored, as is anything that isn't -# valid Python as it stands. +# Read #define's and translate to Python code. +# Handle #include statements. +# Handle #define macros with one argument. +# Anything that isn't recognized or doesn't translate into valid +# Python is ignored. + +# Without filename arguments, acts as a filter. # If one or more filenames are given, output is written to corresponding # filenames in the local directory, translated to all uppercase, with # the extension replaced by ".py". + # By passing one or more options of the form "-i regular_expression" # you can specify additional strings to be ignored. This is useful # e.g. to ignore casts to u_long: simply specify "-i '(u_long)'". # XXX To do: # - turn trailing C comments into Python comments -# - turn C string quotes into Python comments # - turn C Boolean operators "&& || !" into Python "and or not" # - what to do about #if(def)? -# - what to do about #include? -# - what to do about macros with parameters? -# - reject definitions with semicolons in them +# - what to do about macros with multiple parameters? -import sys, regex, string, getopt, os +import sys, regex, regsub, string, getopt, os p_define = regex.compile('^#[\t ]*define[\t ]+\([a-zA-Z0-9_]+\)[\t ]+') +p_macro = regex.compile( + '^#[\t ]*define[\t ]+\([a-zA-Z0-9_]+\)(\([_a-zA-Z][_a-zA-Z0-9]*\))[\t ]+') + +p_include = regex.compile('^#[\t ]*include[\t ]+<\([a-zA-Z0-9_/\.]+\)') + p_comment = regex.compile('/\*\([^*]+\|\*+[^/]\)*\(\*+/\)?') ignores = [p_comment] +p_char = regex.compile("'\(\\\\.[^\\\\]*\|[^\\\\]\)'") + +filedict = {} + def main(): opts, args = getopt.getopt(sys.argv[1:], 'i:') for o, a in opts: @@ -47,40 +58,65 @@ def main(): outfile = outfile + '.py' outfp = open(outfile, 'w') outfp.write('# Generated by h2py from %s\n' % filename) + filedict = {} + if filename[:13] == '/usr/include/': + filedict[filename[13:]] = None process(fp, outfp) outfp.close() fp.close() -def process(fp, outfp): - env = {} +def process(fp, outfp, env = {}): lineno = 0 while 1: line = fp.readline() if not line: break lineno = lineno + 1 - # gobble up continuation lines - while line[-2:] == '\\\n': - nextline = fp.readline() - if not nextline: break - lineno = lineno + 1 - line = line + nextline n = p_define.match(line) if n >= 0: + # gobble up continuation lines + while line[-2:] == '\\\n': + nextline = fp.readline() + if not nextline: break + lineno = lineno + 1 + line = line + nextline name = p_define.group(1) body = line[n:] # replace ignored patterns by spaces for p in ignores: - while p.search(body) >= 0: - a, b = p.regs[0] - body = body[:a] + ' ' + body[b:] + body = regsub.gsub(p, ' ', body) + # replace char literals by ord(...) + body = regsub.gsub(p_char, 'ord(\\0)', body) stmt = '%s = %s\n' % (name, string.strip(body)) ok = 0 try: exec stmt in env - ok = 1 except: sys.stderr.write('Skipping: %s' % stmt) - if ok: + else: outfp.write(stmt) - + n =p_macro.match(line) + if n >= 0: + macro, arg = p_macro.group(1, 2) + body = line[n:] + for p in ignores: + body = regsub.gsub(p, ' ', body) + body = regsub.gsub(p_char, 'ord(\\0)', body) + stmt = 'def %s(%s): return %s\n' % (macro, arg, body) + try: + exec stmt in env + except: + sys.stderr.write('Skipping: %s' % stmt) + else: + outfp.write(stmt) + if p_include.match(line) >= 0: + regs = p_include.regs + a, b = regs[1] + filename = line[a:b] + if not filedict.has_key(filename): + filedict[filename] = None + outfp.write( + '\n# Included from %s\n' % filename) + inclfp = open('/usr/include/' + filename, 'r') + process(inclfp, outfp, env) main() + diff --git a/Tools/scripts/sum5.py b/Tools/scripts/sum5.py new file mode 100755 index 0000000..fdb83fa --- /dev/null +++ b/Tools/scripts/sum5.py @@ -0,0 +1,97 @@ +#! /usr/local/bin/python + +# print md5 checksum for files + +bufsize = 8096 +fnfilter = None +rmode = 'r' + +usage = """ +usage: sum5 [-b] [-t] [-l] [-s bufsize] [file ...] +-b : read files in binary mode +-t : read files in text mode (default) +-l : print last pathname component only +-s bufsize: read buffer size (default %d) +file ... : files to sum; '-' or no files means stdin +""" % bufsize + +import sys +import string +import os +import md5 +import regsub + +StringType = type('') +FileType = type(sys.stdin) + +def sum(*files): + sts = 0 + if files and type(files[-1]) == FileType: + out, files = files[-1], files[:-1] + else: + out = sys.stdout + if len(files) == 1 and type(files[0]) != StringType: + files = files[0] + for f in files: + if type(f) == StringType: + if f == '-': + sts = printsumfp(sys.stdin, '', out) or sts + else: + sts = printsum(f, out) or sts + else: + sts = sum(f, out) or sts + return sts + +def printsum(file, out = sys.stdout): + try: + fp = open(file, rmode) + except IOError, msg: + sys.stderr.write('%s: Can\'t open: %s\n' % (file, msg)) + return 1 + if fnfilter: + file = fnfilter(file) + sts = printsumfp(fp, file, out) + fp.close() + return sts + +def printsumfp(fp, file, out = sys.stdout): + m = md5.md5() + try: + while 1: + data = fp.read(bufsize) + if not data: break + m.update(data) + except IOError, msg: + sys.stderr.write('%s: I/O error: %s\n' % (file, msg)) + return 1 + out.write('%s %s\n' % (hexify(m.digest()), file)) + return 0 + +def hexify(s): + res = '' + for c in s: + res = res + '%02x' % ord(c) + return res + +def main(args = sys.argv[1:], out = sys.stdout): + global fnfilter, rmode, bufsize + import getopt + try: + opts, args = getopt.getopt(args, 'blts:') + except getopt.error, msg: + sys.stderr.write('%s: %s\n%s' % (sys.argv[0], msg, usage)) + return 2 + for o, a in opts: + if o == '-l': + fnfilter = os.path.basename + if o == '-b': + rmode = 'rb' + if o == '-t': + rmode = 'r' + if o == '-s': + bufsize = string.atoi(a) + if not args: args = ['-'] + return sum(args, out) + +if __name__ == '__main__' or __name__ == sys.argv[0]: + sys.exit(main(sys.argv[1:], sys.stdout)) -- cgit v0.12