#!/usr/bin/python -SE from os import system, unlink, kill, fork, popen, path getsize = path.getsize del path from sys import stderr, argv OPTIONS_IN_EVERY_OPTION_STRING = ("-pedantic -Werror -Wfatal-errors -Winit-self " "-Wstrict-overflow=5 -Wfloat-equal -Wundef -Wshadow -Wunsafe-loop-optimizations -funsafe-loop-optimizations " "-Wall -Wextra -Wcast-qual -Wcast-align -Wwrite-strings -Wlogical-op -Waggregate-return -Wredundant-decls -lm -o shiltium") C_OPTIONS = "-Wbad-function-cast -Wdeclaration-after-statement -Wc++-compat -Wstrict-prototypes -Wold-style-definition -Wnested-externs" OPTIONS_FOR_WHEN_OPTIMIZATION_IS_OFF = "-Wformat=0" OPTIMIZATION_OPTIONS = "-s -Wformat=2" option_strings = ( "(gcc) -std=c89", "(gcc) -std=gnu89", "(gcc) -std=c99", "(gcc) -std=gnu99", "(g++) -std=c++98", "(g++) -std=gnu++98", "(g++) -std=c++0x", "(g++) -std=gnu++0x", ) COMMAND_LINE_OPTIONS_FOR_SMALL_EXECUTABLE_MODE = set(("mini", "tiny", "small")) option_strings = [i + " " + OPTIONS_IN_EVERY_OPTION_STRING + " shiltium.c 2>&1; printf $?" for i in option_strings] remove_first_argument = True system("tput reset") if len(argv) > 1 and (argv[1] in ("opt", "optimize", "rel", "release") or argv[1] in COMMAND_LINE_OPTIONS_FOR_SMALL_EXECUTABLE_MODE): status = system( "gcc -DDEBUG=0 " + OPTIONS_IN_EVERY_OPTION_STRING + " " + C_OPTIONS + " " + OPTIMIZATION_OPTIONS + " " + ("-Os" if argv[1] in COMMAND_LINE_OPTIONS_FOR_SMALL_EXECUTABLE_MODE else "-O3") + " -std=c89 -Wdeclaration-after-statement shiltium.c && strip --remove-section .comment --remove-section .note shiltium") if status: raise SystemExit(1) elif len(argv) > 1 and argv[1] in ("lines", "num_lines", "numlines"): print "Lines:\n" system("wc -l *.c *.h") raise SystemExit elif len(argv) > 1 and argv[1] == "ratio": system(argv[0] + " > /dev/null 2>/dev/null") size_of_debugging_version = float(getsize("shiltium")) system(argv[0] + " rel > /dev/null 2>/dev/null") size_of_release_version = float(getsize("shiltium")) print "The debugging version is %.2f times bigger than the release version.\n" % (size_of_debugging_version / size_of_release_version) print "The release version is %.2f%% of the size of the debugging version." % ((size_of_release_version / size_of_debugging_version) * 100) raise SystemExit elif len(argv) > 1 and argv[1] == "check_code": try: from time import time old_time = time() for number, option_string in enumerate(option_strings): for i in range(2): for j in range(2): if not option_string.startswith("(g++) "): if option_string.startswith("(gcc) "): new_option_string = option_string[6:] else: new_option_string = option_string # i == 0 -> 0, otherwise i == 1 -> 3 new_option_string = "gcc -O%d -DDEBUG=%d %s" % (i * 3, j, new_option_string + " " + C_OPTIONS) print new_option_string stdout_of_command = popen(new_option_string).read() if stdout_of_command != '0': raise SystemExit if not option_string.startswith("(gcc) "): if option_string.startswith("(g++) "): new_option_string = option_string[6:] else: new_option_string = option_string # i == 0 -> 0, otherwise i == 1 -> 3 new_option_string = "g++ -O%d -DDEBUG=%d %s" % (i * 3, j, new_option_string) print new_option_string stdout_of_command = popen(new_option_string).read() if stdout_of_command != '0': raise SystemExit normal = True except SystemExit: normal = False try: unlink("shiltium") except: pass if normal: print ("\x1bc\x1b[!p\x1b[?3;4l\x1b[4l\x1b>All the code is perfect! It compiles in every version of C and C++ " + "that was checked! The code compiled as C89, C99, C++98 and C++0x, and all the GNU variants of them " + "without any warnings or errors at all! The code was compiled in %d different ways and they all compiled properly!\n" % (len(option_strings) * 4)) print "It took %s seconds to check.\n" % (time() - old_time) else: print >> stderr, "\n" + stdout_of_command[:-2] raise SystemExit else: status = system("gcc -g -std=c89 -DDEBUG=1 " + OPTIONS_IN_EVERY_OPTION_STRING + " " + C_OPTIONS + " " + OPTIONS_FOR_WHEN_OPTIMIZATION_IS_OFF + " shiltium.c") if status: raise SystemExit(1) remove_first_argument = False if remove_first_argument: args = " ".join(argv[2:]) else: if len(argv) > 1: args = argv[1] else: args = "" system("./shiltium " + args)