blob: 2c948f75db12c2513c3bd2acce432349e41cf1ad [file] [log] [blame]
Guido van Rossumf06ee5f1996-11-27 19:52:01 +00001#! /usr/bin/env python
Guido van Rossumca7b2131992-07-07 09:11:53 +00002
Guido van Rossumff535a11992-08-10 10:42:36 +00003# Emulate some Perl command line options.
4# Usage: pp [-a] [-c] [-d] [-e scriptline] [-F fieldsep] [-n] [-p] [file] ...
5# Where the options mean the following:
6# -a : together with -n or -p, splits each line into list F
7# -c : check syntax only, do not execute any code
8# -d : run the script under the debugger, pdb
9# -e scriptline : gives one line of the Python script; may be repeated
10# -F fieldsep : sets the field separator for the -a option [not in Perl]
11# -n : runs the script for each line of input
12# -p : prints the line after the script has run
13# When no script lines have been passed, the first file argument
14# contains the script. With -n or -p, the remaining arguments are
15# read as input to the script, line by line. If a file is '-'
16# or missing, standard input is read.
17
18# XXX To do:
19# - add -i extension option (change files in place)
20# - make a single loop over the files and lines (changes effect of 'break')?
21# - add an option to specify the record separator
22# - except for -n/-p, run directly from the file if at all possible
Guido van Rossumca7b2131992-07-07 09:11:53 +000023
24import sys
Guido van Rossumca7b2131992-07-07 09:11:53 +000025import getopt
26
27FS = ''
Guido van Rossumff535a11992-08-10 10:42:36 +000028SCRIPT = []
29AFLAG = 0
30CFLAG = 0
31DFLAG = 0
32NFLAG = 0
33PFLAG = 0
Guido van Rossumca7b2131992-07-07 09:11:53 +000034
Guido van Rossumff535a11992-08-10 10:42:36 +000035try:
Tim Peterse6ddc8b2004-07-18 05:56:09 +000036 optlist, ARGS = getopt.getopt(sys.argv[1:], 'acde:F:np')
Guido van Rossumb940e112007-01-10 16:19:56 +000037except getopt.error as msg:
Georg Brandl22fff432009-10-27 20:19:02 +000038 sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
Tim Peterse6ddc8b2004-07-18 05:56:09 +000039 sys.exit(2)
Guido van Rossumff535a11992-08-10 10:42:36 +000040
Guido van Rossumca7b2131992-07-07 09:11:53 +000041for option, optarg in optlist:
Tim Peterse6ddc8b2004-07-18 05:56:09 +000042 if option == '-a':
43 AFLAG = 1
44 elif option == '-c':
45 CFLAG = 1
46 elif option == '-d':
47 DFLAG = 1
48 elif option == '-e':
Georg Brandl22fff432009-10-27 20:19:02 +000049 for line in optarg.split('\n'):
Tim Peterse6ddc8b2004-07-18 05:56:09 +000050 SCRIPT.append(line)
51 elif option == '-F':
52 FS = optarg
53 elif option == '-n':
54 NFLAG = 1
55 PFLAG = 0
56 elif option == '-p':
57 NFLAG = 1
58 PFLAG = 1
59 else:
Collin Winter6f2df4d2007-07-17 20:59:35 +000060 print(option, 'not recognized???')
Guido van Rossumca7b2131992-07-07 09:11:53 +000061
Guido van Rossumff535a11992-08-10 10:42:36 +000062if not ARGS: ARGS.append('-')
Guido van Rossumca7b2131992-07-07 09:11:53 +000063
Guido van Rossumff535a11992-08-10 10:42:36 +000064if not SCRIPT:
Tim Peterse6ddc8b2004-07-18 05:56:09 +000065 if ARGS[0] == '-':
66 fp = sys.stdin
67 else:
68 fp = open(ARGS[0], 'r')
69 while 1:
70 line = fp.readline()
71 if not line: break
72 SCRIPT.append(line[:-1])
73 del fp
74 del ARGS[0]
75 if not ARGS: ARGS.append('-')
Guido van Rossumca7b2131992-07-07 09:11:53 +000076
Guido van Rossumff535a11992-08-10 10:42:36 +000077if CFLAG:
Tim Peterse6ddc8b2004-07-18 05:56:09 +000078 prologue = ['if 0:']
79 epilogue = []
Guido van Rossumff535a11992-08-10 10:42:36 +000080elif NFLAG:
Tim Peterse6ddc8b2004-07-18 05:56:09 +000081 # Note that it is on purpose that AFLAG and PFLAG are
82 # tested dynamically each time through the loop
Georg Brandl22fff432009-10-27 20:19:02 +000083 prologue = [
84 'LINECOUNT = 0',
85 'for FILE in ARGS:',
86 ' \tif FILE == \'-\':',
87 ' \t \tFP = sys.stdin',
88 ' \telse:',
89 ' \t \tFP = open(FILE, \'r\')',
90 ' \tLINENO = 0',
91 ' \twhile 1:',
92 ' \t \tLINE = FP.readline()',
93 ' \t \tif not LINE: break',
94 ' \t \tLINENO = LINENO + 1',
95 ' \t \tLINECOUNT = LINECOUNT + 1',
96 ' \t \tL = LINE[:-1]',
97 ' \t \taflag = AFLAG',
98 ' \t \tif aflag:',
99 ' \t \t \tif FS: F = L.split(FS)',
100 ' \t \t \telse: F = L.split()'
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000101 ]
Georg Brandl22fff432009-10-27 20:19:02 +0000102 epilogue = [
103 ' \t \tif not PFLAG: continue',
104 ' \t \tif aflag:',
105 ' \t \t \tif FS: print(FS.join(F))',
106 ' \t \t \telse: print(\' \'.join(F))',
107 ' \t \telse: print(L)',
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000108 ]
Guido van Rossumff535a11992-08-10 10:42:36 +0000109else:
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000110 prologue = ['if 1:']
111 epilogue = []
Guido van Rossumca7b2131992-07-07 09:11:53 +0000112
113# Note that we indent using tabs only, so that any indentation style
114# used in 'command' will come out right after re-indentation.
115
Georg Brandl22fff432009-10-27 20:19:02 +0000116program = '\n'.join(prologue) + '\n'
Guido van Rossumff535a11992-08-10 10:42:36 +0000117for line in SCRIPT:
Georg Brandl22fff432009-10-27 20:19:02 +0000118 program += ' \t \t' + line + '\n'
119program += '\n'.join(epilogue) + '\n'
Guido van Rossumca7b2131992-07-07 09:11:53 +0000120
Guido van Rossum3b0a3292002-08-09 16:38:32 +0000121if DFLAG:
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000122 import pdb
Georg Brandl22fff432009-10-27 20:19:02 +0000123 pdb.run(program)
Guido van Rossum3b0a3292002-08-09 16:38:32 +0000124else:
Georg Brandl22fff432009-10-27 20:19:02 +0000125 exec(program)