def strip_comments(file_wpath, harness_dir, env): import os import subprocess import shutil from system.utils import which # grab proper g++ command gpp = which(env["compiler"]) if gpp is None: message = "g++ compiler not found, could not strip comments" compiled = False return {"success": compiled, "message": message} # pull out file path to trim any error messages to just name or local path file_path = file_wpath[0:file_wpath.rfind("/")+1] # set up path to includes directory include_path = os.path.join(harness_dir, env["includes_dir"]) # check if working directory exists, if not make one working_dir = os.path.join(harness_dir, env["working_dir"]) if not os.path.exists(working_dir): os.mkdir(working_dir) made_working = True else: made_working = False # attempt to compiler preprocessor to strip comments out_file_path = os.path.join(working_dir, "out.txt") try: with open(out_file_path, 'w') as outFile: r = check_output([gpp, "-fpreprocessed", "-E", "-I", include_path, file_wpath], stdout=outFile, stderr=nullFile) compiled = True message = open(out_file_path).read() except SystemError: message = "Stripping comments from file failed" compiled = False if compiled: message = message[message.find("\n"):] # remove the working directory if function created it if made_working: shutil.rmtree(working_dir) elif os.path.isfile(out_file_path): os.remove(out_file_path) return {"success": compiled, "message": message}
def indent_args(f, p, arg_list, env): import os import subprocess import shutil from system.utils import which from system.procs import check_call files_to_remove = [] indented = False message = "Could not indent the file" error = None # send indent output to standard output arg_list.append("-st") # grab the system's indent command indent = which("indent") if indent is None: indented = False message = "No indent command found on system" error = None return {"success": indented, "message": message, "errors": error} # create a working directory if one doesn't exist working_dir = os.path.join(p, env["working_dir"]) if not os.path.exists(working_dir): os.mkdir(working_dir) made_working = True else: made_working = False # attempt compilation as compile errors may cause odd indent errors # grab proper g++ command gpp = which(env["compiler"]) # pull out file path to trim any error messages to just name or local path file_wpath = f file_path = file_wpath[0:file_wpath.rfind("/")+1] # set up path to includes directory include_path = os.path.join(p, env["includes_dir"]) # set up path to output exe output_wpath = os.path.join(working_dir, "indent_compile") # open /dev/null for dismissing output or errors nullFile = open(os.devnull, 'w') # attempt compilation try: r = check_call([gpp, "-o",output_wpath, "-I", include_path, file_wpath], stdout=nullFile, stderr=nullFile) compiled = True except SystemError: compiled = False errf = os.path.join(working_dir, "indent_errors.txt") files_to_remove.append(errf) indentf = os.path.join(working_dir, "indent_out.cpp") files_to_remove.append(indentf) try: command = [indent] for arg in arg_list: command.append(arg) command.append(f) # run indent command with open(errf, 'w') as err_file: with open(indentf, 'w') as indentFile: r = check_call(command, stdout=indentFile, stderr=err_file) message = open(indentf).read() except SystemError: message = open(indentf).read() # Indent always does something even when errors exist indented = True # determine if error messages exist with open(errf, 'r') as err_file: error = err_file.read() if len(error) == 0: error = None else: error = error.replace(f[0:f.rfind("/")+1], "").replace("indent: ", "") error = error.replace("\n\n", "\n") error = error.strip() # didn't compile pre-pend a warning about indent error messages if not compiled: pre = "WARNING: Failed compilation may result in additional errors from indent command.\n\n" error = pre + error # remove working directory if this process created it otherwise all files if made_working: shutil.rmtree(working_dir) elif len(files_to_remove) > 0: for f in files_to_remove: if os.path.isfile(f): os.remove(f) return {"success": indented, "message": message, "errors": error}
def globals_exist(test, harness_dir, source, env, deduction): import os import shutil import re from system.utils import which from system.procs import check_call # intialize to empty list of global variables vars = [] files_to_remove = [] # make sure the commands exist nm = which("nm") gpp = which(env["compiler"]) if nm == None or gpp == None: return None # check if working directory exists, if not make one working_dir = os.path.join(harness_dir, env["working_dir"]) if not os.path.exists(working_dir): os.mkdir(working_dir) made_working = True else: made_working = False FNULL = open(os.devnull, 'w') try: # compile the object file # set up path to includes directory include_path = os.path.join(harness_dir, env["includes_dir"]) object_file = source.name[0:source.name.find(".")] + ".o" obj_loc = os.path.join(working_dir, object_file) files_to_remove.append(obj_loc) check_call([gpp, "-c", "-o", obj_loc, "-I", include_path, source.file_loc], stdout=FNULL, stderr=FNULL) # get object symbols symf = os.path.join(working_dir, "symbols.txt") files_to_remove.append(symf) cmd = " ".join([nm, obj_loc]) with open(symf, 'w') as sym_file: check_call([nm, obj_loc], stdout=sym_file, stderr=FNULL) # search for global variables line in symbols file var_lines = [] with open(symf, 'r') as sym_file: for line in sym_file: if re.search('[0-9A-Fa-f]* [BCDGRS]', line): var_lines.append(line) # append last item (the variable name) to variables list for line in var_lines: if len(line) > 0: vars.append(line.strip().split(" ")[-1]) except SystemError as e: # TODO: determine what to do in except clause, outputing error cause issue? FNULL.close() if made_working: shutil.rmtree(working_dir) elif len(files_to_remove) > 0: for f in files_to_remove: if os.path.isfile(f): os.remove(f) return None # remove working directory if created it otherwise remove files created if made_working: shutil.rmtree(working_dir) elif len(files_to_remove) > 0: for f in files_to_remove: if os.path.isfile(f): os.remove(f) FNULL.close() test.score = -1 * deduction * len(vars) return vars
def compile_single(file_wpath, output_wpath, harness_dir, env): import os import subprocess import shutil from system.utils import which # Open /dev/null for dismissing errors or output nullFile = open(os.devnull, 'w+') # grab proper g++ command gpp = which(env["compiler"]) # set up successful message message = "Compiled successfully" # pull out file path to trim any error messages to just name or local path file_path = file_wpath[0:file_wpath.rfind("/")+1] # set up path to includes directory include_path = os.path.join(harness_dir, env["includes_dir"]) # check if working directory exists, if not make one working_dir = os.path.join(harness_dir, env["working_dir"]) if not os.path.exists(working_dir): os.mkdir(working_dir) made_working = True else: made_working = False err_file_path = os.path.join(working_dir, "errors.txt") # attempt to compile any provided source code obj_files = [] compiled = True if env["code_provided"]: prov_dir = os.path.join(harness_dir, env["provided_dir"]) files = os.listdir(prov_dir) for file in files: if file.endswith(".o"): dest_path = os.path.join(working_dir, file) file_path = os.path.join(prov_dir, file) copyfile(file_path, dest_path) elif file.endswith(".cpp"): obj_name = file[0:file.find(".cpp")] + ".o" obj_path = os.path.join(working_dir, obj_name) file_path = os.path.join(prov_dir, file) try: r = check_call([gpp, "-c", "-o", obj_path, "-I", include_path, file_path], stdout=nullFile, stderr=nullFile) compiled = True obj_files.append(obj_path) except SystemError: compiled = False break # attempt compilation if compiled: try: cmd = [gpp, "-o", output_wpath, "-I", include_path] for f in obj_files: cmd.append(f) cmd.append(file_wpath) with open(err_file_path, 'w+') as errFile: r = check_call(cmd, stdout=nullFile, stderr=errFile) compiled = True except SystemError: # grab the errors from the error file then eliminate it message = open(err_file_path).read().replace(file_path, "") compiled = False # remove the working directory if function created it if made_working: shutil.rmtree(working_dir) elif os.path.isfile(err_file_path): os.remove(err_file_path) return {"success": compiled, "message": message}