| #! /usr/bin/env python | |
| # Emulate some Perl command line options. | |
| # Usage: pp [-a] [-c] [-d] [-e scriptline] [-F fieldsep] [-n] [-p] [file] ... | |
| # Where the options mean the following: | |
| # -a : together with -n or -p, splits each line into list F | |
| # -c : check syntax only, do not execute any code | |
| # -d : run the script under the debugger, pdb | |
| # -e scriptline : gives one line of the Python script; may be repeated | |
| # -F fieldsep : sets the field separator for the -a option [not in Perl] | |
| # -n : runs the script for each line of input | |
| # -p : prints the line after the script has run | |
| # When no script lines have been passed, the first file argument | |
| # contains the script. With -n or -p, the remaining arguments are | |
| # read as input to the script, line by line. If a file is '-' | |
| # or missing, standard input is read. | |
| # XXX To do: | |
| # - add -i extension option (change files in place) | |
| # - make a single loop over the files and lines (changes effect of 'break')? | |
| # - add an option to specify the record separator | |
| # - except for -n/-p, run directly from the file if at all possible | |
| import sys | |
| import getopt | |
| FS = '' | |
| SCRIPT = [] | |
| AFLAG = 0 | |
| CFLAG = 0 | |
| DFLAG = 0 | |
| NFLAG = 0 | |
| PFLAG = 0 | |
| try: | |
| optlist, ARGS = getopt.getopt(sys.argv[1:], 'acde:F:np') | |
| except getopt.error, msg: | |
| sys.stderr.write('%s: %s\n' % (sys.argv[0], msg)) | |
| sys.exit(2) | |
| for option, optarg in optlist: | |
| if option == '-a': | |
| AFLAG = 1 | |
| elif option == '-c': | |
| CFLAG = 1 | |
| elif option == '-d': | |
| DFLAG = 1 | |
| elif option == '-e': | |
| for line in optarg.split('\n'): | |
| SCRIPT.append(line) | |
| elif option == '-F': | |
| FS = optarg | |
| elif option == '-n': | |
| NFLAG = 1 | |
| PFLAG = 0 | |
| elif option == '-p': | |
| NFLAG = 1 | |
| PFLAG = 1 | |
| else: | |
| print option, 'not recognized???' | |
| if not ARGS: ARGS.append('-') | |
| if not SCRIPT: | |
| if ARGS[0] == '-': | |
| fp = sys.stdin | |
| else: | |
| fp = open(ARGS[0], 'r') | |
| while 1: | |
| line = fp.readline() | |
| if not line: break | |
| SCRIPT.append(line[:-1]) | |
| del fp | |
| del ARGS[0] | |
| if not ARGS: ARGS.append('-') | |
| if CFLAG: | |
| prologue = ['if 0:'] | |
| epilogue = [] | |
| elif NFLAG: | |
| # Note that it is on purpose that AFLAG and PFLAG are | |
| # tested dynamically each time through the loop | |
| prologue = [ | |
| 'LINECOUNT = 0', | |
| 'for FILE in ARGS:', | |
| ' \tif FILE == \'-\':', | |
| ' \t \tFP = sys.stdin', | |
| ' \telse:', | |
| ' \t \tFP = open(FILE, \'r\')', | |
| ' \tLINENO = 0', | |
| ' \twhile 1:', | |
| ' \t \tLINE = FP.readline()', | |
| ' \t \tif not LINE: break', | |
| ' \t \tLINENO = LINENO + 1', | |
| ' \t \tLINECOUNT = LINECOUNT + 1', | |
| ' \t \tL = LINE[:-1]', | |
| ' \t \taflag = AFLAG', | |
| ' \t \tif aflag:', | |
| ' \t \t \tif FS: F = L.split(FS)', | |
| ' \t \t \telse: F = L.split()' | |
| ] | |
| epilogue = [ | |
| ' \t \tif not PFLAG: continue', | |
| ' \t \tif aflag:', | |
| ' \t \t \tif FS: print FS.join(F)', | |
| ' \t \t \telse: print \' \'.join(F)', | |
| ' \t \telse: print L', | |
| ] | |
| else: | |
| prologue = ['if 1:'] | |
| epilogue = [] | |
| # Note that we indent using tabs only, so that any indentation style | |
| # used in 'command' will come out right after re-indentation. | |
| program = '\n'.join(prologue) + '\n' | |
| for line in SCRIPT: | |
| program += ' \t \t' + line + '\n' | |
| program += '\n'.join(epilogue) + '\n' | |
| import tempfile | |
| fp = tempfile.NamedTemporaryFile() | |
| fp.write(program) | |
| fp.flush() | |
| if DFLAG: | |
| import pdb | |
| pdb.run('execfile(%r)' % (fp.name,)) | |
| else: | |
| execfile(fp.name) |