1 | #! /usr/bin/env python
|
---|
2 |
|
---|
3 | """finddiv - a grep-like tool that looks for division operators.
|
---|
4 |
|
---|
5 | Usage: finddiv [-l] file_or_directory ...
|
---|
6 |
|
---|
7 | For directory arguments, all files in the directory whose name ends in
|
---|
8 | .py are processed, and subdirectories are processed recursively.
|
---|
9 |
|
---|
10 | This actually tokenizes the files to avoid false hits in comments or
|
---|
11 | strings literals.
|
---|
12 |
|
---|
13 | By default, this prints all lines containing a / or /= operator, in
|
---|
14 | grep -n style. With the -l option specified, it prints the filename
|
---|
15 | of files that contain at least one / or /= operator.
|
---|
16 | """
|
---|
17 |
|
---|
18 | import os
|
---|
19 | import sys
|
---|
20 | import getopt
|
---|
21 | import tokenize
|
---|
22 |
|
---|
23 | def main():
|
---|
24 | try:
|
---|
25 | opts, args = getopt.getopt(sys.argv[1:], "lh")
|
---|
26 | except getopt.error, msg:
|
---|
27 | usage(msg)
|
---|
28 | return 2
|
---|
29 | if not args:
|
---|
30 | usage("at least one file argument is required")
|
---|
31 | return 2
|
---|
32 | listnames = 0
|
---|
33 | for o, a in opts:
|
---|
34 | if o == "-h":
|
---|
35 | print __doc__
|
---|
36 | return
|
---|
37 | if o == "-l":
|
---|
38 | listnames = 1
|
---|
39 | exit = None
|
---|
40 | for filename in args:
|
---|
41 | x = process(filename, listnames)
|
---|
42 | exit = exit or x
|
---|
43 | return exit
|
---|
44 |
|
---|
45 | def usage(msg):
|
---|
46 | sys.stderr.write("%s: %s\n" % (sys.argv[0], msg))
|
---|
47 | sys.stderr.write("Usage: %s [-l] file ...\n" % sys.argv[0])
|
---|
48 | sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0])
|
---|
49 |
|
---|
50 | def process(filename, listnames):
|
---|
51 | if os.path.isdir(filename):
|
---|
52 | return processdir(filename, listnames)
|
---|
53 | try:
|
---|
54 | fp = open(filename)
|
---|
55 | except IOError, msg:
|
---|
56 | sys.stderr.write("Can't open: %s\n" % msg)
|
---|
57 | return 1
|
---|
58 | g = tokenize.generate_tokens(fp.readline)
|
---|
59 | lastrow = None
|
---|
60 | for type, token, (row, col), end, line in g:
|
---|
61 | if token in ("/", "/="):
|
---|
62 | if listnames:
|
---|
63 | print filename
|
---|
64 | break
|
---|
65 | if row != lastrow:
|
---|
66 | lastrow = row
|
---|
67 | print "%s:%d:%s" % (filename, row, line),
|
---|
68 | fp.close()
|
---|
69 |
|
---|
70 | def processdir(dir, listnames):
|
---|
71 | try:
|
---|
72 | names = os.listdir(dir)
|
---|
73 | except os.error, msg:
|
---|
74 | sys.stderr.write("Can't list directory: %s\n" % dir)
|
---|
75 | return 1
|
---|
76 | files = []
|
---|
77 | for name in names:
|
---|
78 | fn = os.path.join(dir, name)
|
---|
79 | if os.path.normcase(fn).endswith(".py") or os.path.isdir(fn):
|
---|
80 | files.append(fn)
|
---|
81 | files.sort(lambda a, b: cmp(os.path.normcase(a), os.path.normcase(b)))
|
---|
82 | exit = None
|
---|
83 | for fn in files:
|
---|
84 | x = process(fn, listnames)
|
---|
85 | exit = exit or x
|
---|
86 | return exit
|
---|
87 |
|
---|
88 | if __name__ == "__main__":
|
---|
89 | sys.exit(main())
|
---|