blob: d21253cf1c8a14c9b42fd9976f7cfe1b24723da9 [file] [log] [blame]
Benjamin Peterson90f5ba52010-03-11 22:53:45 +00001#! /usr/bin/env python3
Guido van Rossum43db62e2001-09-02 04:43:30 +00002
3"""finddiv - a grep-like tool that looks for division operators.
4
5Usage: finddiv [-l] file_or_directory ...
6
7For directory arguments, all files in the directory whose name ends in
8.py are processed, and subdirectories are processed recursively.
9
10This actually tokenizes the files to avoid false hits in comments or
11strings literals.
12
13By default, this prints all lines containing a / or /= operator, in
14grep -n style. With the -l option specified, it prints the filename
15of files that contain at least one / or /= operator.
16"""
17
18import os
19import sys
20import getopt
21import tokenize
22
23def main():
24 try:
25 opts, args = getopt.getopt(sys.argv[1:], "lh")
Guido van Rossumb940e112007-01-10 16:19:56 +000026 except getopt.error as msg:
Guido van Rossum43db62e2001-09-02 04:43:30 +000027 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":
Collin Winter6afaeb72007-08-03 17:06:41 +000035 print(__doc__)
Guido van Rossum43db62e2001-09-02 04:43:30 +000036 return
37 if o == "-l":
38 listnames = 1
39 exit = None
Andrew M. Kuchlingac6df952003-05-13 18:14:25 +000040 for filename in args:
41 x = process(filename, listnames)
Guido van Rossum43db62e2001-09-02 04:43:30 +000042 exit = exit or x
43 return exit
44
45def 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
Andrew M. Kuchlingac6df952003-05-13 18:14:25 +000050def process(filename, listnames):
51 if os.path.isdir(filename):
52 return processdir(filename, listnames)
Guido van Rossum43db62e2001-09-02 04:43:30 +000053 try:
Andrew M. Kuchlingac6df952003-05-13 18:14:25 +000054 fp = open(filename)
Guido van Rossumb940e112007-01-10 16:19:56 +000055 except IOError as msg:
Guido van Rossum43db62e2001-09-02 04:43:30 +000056 sys.stderr.write("Can't open: %s\n" % msg)
57 return 1
Serhiy Storchaka172bb392019-03-30 08:33:02 +020058 with fp:
59 g = tokenize.generate_tokens(fp.readline)
60 lastrow = None
61 for type, token, (row, col), end, line in g:
62 if token in ("/", "/="):
63 if listnames:
64 print(filename)
65 break
66 if row != lastrow:
67 lastrow = row
68 print("%s:%d:%s" % (filename, row, line), end=' ')
Guido van Rossum43db62e2001-09-02 04:43:30 +000069
70def processdir(dir, listnames):
71 try:
72 names = os.listdir(dir)
Andrew Svetlov8b33dd82012-12-24 19:58:48 +020073 except OSError as msg:
Guido van Rossum43db62e2001-09-02 04:43:30 +000074 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)
Raymond Hettingerd4cb56d2008-01-30 02:55:10 +000081 files.sort(key=os.path.normcase)
Guido van Rossum43db62e2001-09-02 04:43:30 +000082 exit = None
83 for fn in files:
84 x = process(fn, listnames)
85 exit = exit or x
86 return exit
87
88if __name__ == "__main__":
89 sys.exit(main())