17db96d56Sopenharmony_ci#! /usr/bin/env python3 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci"""finddiv - a grep-like tool that looks for division operators. 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ciUsage: finddiv [-l] file_or_directory ... 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ciFor directory arguments, all files in the directory whose name ends in 87db96d56Sopenharmony_ci.py are processed, and subdirectories are processed recursively. 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ciThis actually tokenizes the files to avoid false hits in comments or 117db96d56Sopenharmony_cistrings literals. 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_ciBy default, this prints all lines containing a / or /= operator, in 147db96d56Sopenharmony_cigrep -n style. With the -l option specified, it prints the filename 157db96d56Sopenharmony_ciof files that contain at least one / or /= operator. 167db96d56Sopenharmony_ci""" 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ciimport os 197db96d56Sopenharmony_ciimport sys 207db96d56Sopenharmony_ciimport getopt 217db96d56Sopenharmony_ciimport tokenize 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_cidef main(): 247db96d56Sopenharmony_ci try: 257db96d56Sopenharmony_ci opts, args = getopt.getopt(sys.argv[1:], "lh") 267db96d56Sopenharmony_ci except getopt.error as msg: 277db96d56Sopenharmony_ci usage(msg) 287db96d56Sopenharmony_ci return 2 297db96d56Sopenharmony_ci if not args: 307db96d56Sopenharmony_ci usage("at least one file argument is required") 317db96d56Sopenharmony_ci return 2 327db96d56Sopenharmony_ci listnames = 0 337db96d56Sopenharmony_ci for o, a in opts: 347db96d56Sopenharmony_ci if o == "-h": 357db96d56Sopenharmony_ci print(__doc__) 367db96d56Sopenharmony_ci return 377db96d56Sopenharmony_ci if o == "-l": 387db96d56Sopenharmony_ci listnames = 1 397db96d56Sopenharmony_ci exit = None 407db96d56Sopenharmony_ci for filename in args: 417db96d56Sopenharmony_ci x = process(filename, listnames) 427db96d56Sopenharmony_ci exit = exit or x 437db96d56Sopenharmony_ci return exit 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_cidef usage(msg): 467db96d56Sopenharmony_ci sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) 477db96d56Sopenharmony_ci sys.stderr.write("Usage: %s [-l] file ...\n" % sys.argv[0]) 487db96d56Sopenharmony_ci sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0]) 497db96d56Sopenharmony_ci 507db96d56Sopenharmony_cidef process(filename, listnames): 517db96d56Sopenharmony_ci if os.path.isdir(filename): 527db96d56Sopenharmony_ci return processdir(filename, listnames) 537db96d56Sopenharmony_ci try: 547db96d56Sopenharmony_ci fp = open(filename) 557db96d56Sopenharmony_ci except IOError as msg: 567db96d56Sopenharmony_ci sys.stderr.write("Can't open: %s\n" % msg) 577db96d56Sopenharmony_ci return 1 587db96d56Sopenharmony_ci with fp: 597db96d56Sopenharmony_ci g = tokenize.generate_tokens(fp.readline) 607db96d56Sopenharmony_ci lastrow = None 617db96d56Sopenharmony_ci for type, token, (row, col), end, line in g: 627db96d56Sopenharmony_ci if token in ("/", "/="): 637db96d56Sopenharmony_ci if listnames: 647db96d56Sopenharmony_ci print(filename) 657db96d56Sopenharmony_ci break 667db96d56Sopenharmony_ci if row != lastrow: 677db96d56Sopenharmony_ci lastrow = row 687db96d56Sopenharmony_ci print("%s:%d:%s" % (filename, row, line), end=' ') 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_cidef processdir(dir, listnames): 717db96d56Sopenharmony_ci try: 727db96d56Sopenharmony_ci names = os.listdir(dir) 737db96d56Sopenharmony_ci except OSError as msg: 747db96d56Sopenharmony_ci sys.stderr.write("Can't list directory: %s\n" % dir) 757db96d56Sopenharmony_ci return 1 767db96d56Sopenharmony_ci files = [] 777db96d56Sopenharmony_ci for name in names: 787db96d56Sopenharmony_ci fn = os.path.join(dir, name) 797db96d56Sopenharmony_ci if os.path.normcase(fn).endswith(".py") or os.path.isdir(fn): 807db96d56Sopenharmony_ci files.append(fn) 817db96d56Sopenharmony_ci files.sort(key=os.path.normcase) 827db96d56Sopenharmony_ci exit = None 837db96d56Sopenharmony_ci for fn in files: 847db96d56Sopenharmony_ci x = process(fn, listnames) 857db96d56Sopenharmony_ci exit = exit or x 867db96d56Sopenharmony_ci return exit 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ciif __name__ == "__main__": 897db96d56Sopenharmony_ci sys.exit(main()) 90