package SapforTestingSystem; import Common.Constants; import Common.Global; import Common.Utils.Utils; import GlobalData.Tasks.TaskState; import ProjectData.Files.DBProjectFile; import ProjectData.LanguageName; import ProjectData.Messages.Errors.MessageError; import ProjectData.Project.db_project_info; import SapforTestingSystem.Json.SapforConfiguration_json; import SapforTestingSystem.Json.SapforVersion_json; import SapforTestingSystem.SapforTask.SapforTask; import Visual_DVM_2021.Passes.PassCode_2021; import Visual_DVM_2021.Passes.PassException; import Visual_DVM_2021.Passes.Pass_2021; import org.apache.commons.io.FileUtils; import java.io.File; import java.nio.charset.Charset; import java.nio.file.Paths; import java.util.Arrays; import java.util.Comparator; import java.util.Vector; import static java.lang.Character.isDigit; public class PerformSapforTask extends Pass_2021 { @Override public String getDescription() { return "Запуск задачи SAPFOR"; } @Override protected boolean needsAnimation() { return false; } //-- File sapfor_drv; SapforConfiguration_json sapforConfiguration_json; //----- File parentTask; File task; //----- Process process = null; int exit_code = Constants.Nan; //---- File outputFile = null; File errorsFile = null; //-- Vector outputLines; Vector errorsLines; //--- @Override protected boolean canStart(Object... args) throws Exception { sapfor_drv = (File) args[0]; sapforConfiguration_json = (SapforConfiguration_json) args[1]; String testDescription = (String) args[2]; target = (SapforTask) args[3]; //--->> parentTask = Paths.get(Global.Home, sapforConfiguration_json.id, testDescription).toFile(); task = null; //--->> target.sapfor_configuration_id = sapforConfiguration_json.id; target.test_description = testDescription; target.root = parentTask.getAbsolutePath(); return true; } protected static boolean checkLines(Vector lines) { for (String line : lines) { if (line.toLowerCase().contains("internal error")) { return false; } if (line.toLowerCase().contains("exception")) { return false; } if (line.contains("[ERROR]")) { return false; } if (line.toLowerCase().contains("segmentation fault")) { return false; } } return true; } protected boolean performSapforScript(String name, File workspace, String command, String outName, String errName) throws Exception { process = null; exit_code = Constants.Nan; //--- File data_workspace = new File(workspace, Constants.data); Utils.CheckDirectory(data_workspace); outputFile = new File(data_workspace, outName); errorsFile = new File(data_workspace, errName); Utils.delete_with_check(outputFile); Utils.delete_with_check(errorsFile); //--- File file = new File(data_workspace, name + (Global.isWindows ? ".bat" : ".sh")); FileUtils.write(file, Utils.DQuotes(sapfor_drv.getAbsolutePath()) + (sapforConfiguration_json.flags.isEmpty() ? "" : (" " + sapforConfiguration_json.flags)) + " -noLogo" + " " + command + " 1>" + Utils.DQuotes(outputFile.getAbsolutePath()) + " 2>" + Utils.DQuotes(errorsFile.getAbsolutePath()), Charset.defaultCharset()); if (!file.setExecutable(true)) throw new Exception("Не удалось сделать файл скрипта " + name + " исполняемым!"); //-- ProcessBuilder procBuilder = new ProcessBuilder(file.getAbsolutePath()); procBuilder.directory(workspace); process = procBuilder.start(); exit_code = process.waitFor(); if (exit_code != 0) throw new PassException("Процесс завершился с кодом " + exit_code); process = null; //--- outputLines = new Vector<>(FileUtils.readLines(outputFile)); errorsLines = new Vector<>(FileUtils.readLines(errorsFile)); return checkLines(outputLines) && checkLines(errorsLines); } protected boolean parse() throws Exception { if (performSapforScript("parse", parentTask, "-parse *.f *.for *.fdv *.f90 *.f77", "parse_out.txt", "parse_err.txt") && (new File(parentTask, "dvm.proj")).exists()) { return true; } else { target.state = TaskState.DoneWithErrors; return false; } } protected boolean transformation(PassCode_2021 code) throws Exception { task = new File(parentTask, "v1"); Utils.CheckAndCleanDirectory(task); //папка для преобразования. if (performSapforScript("transformation", parentTask, code.getTestingCommand() + " -F " + Utils.DQuotes(task.getAbsolutePath()), "out.txt", "err.txt" )) { target.state = TaskState.Done; target.versions.add(new SapforVersion_json(task.getAbsolutePath(), code.getDescription())); parentTask = task; return true; } Utils.delete_with_check(task); target.state = TaskState.DoneWithErrors; return false; } protected boolean variants() throws Exception { if (performSapforScript("create_variants", parentTask, " -t 13 -allVars", "out.txt", "err.txt" )) { //найти папки с вариантами. File[] files_ = parentTask.listFiles((dir, name) -> dir.isDirectory() && Utils.isParallelVersionName(name)); if ((files_ != null) && (files_.length > 0)) { Vector files = new Vector<>(Arrays.asList(files_)); files.sort(Comparator.comparingInt(o -> Integer.parseInt(o.getName().substring(1)))); target.state = TaskState.Done; for (File file : files) target.variants.add(new SapforVersion_json(file.getAbsolutePath(), PassCode_2021.SPF_CreateParallelVariant.getDescription())); return true; } } target.state = TaskState.DoneWithErrors; return false; } //-------------------------------------------------->> public MessageError unpackMessage(String line_in) throws Exception { MessageError res = new MessageError(); res.file = ""; res.line = Constants.Nan; res.value = ""; String line = line_in.substring(9); System.out.println(line); int i = 0; int s = 0; String lexeme = ""; //#1020: red43.fdv: line 988]: Active DVM directives are not supported (turn on DVM-directive support option) for (char c : line.toCharArray()) { // System.out.print(""); // System.out.println(c); switch (s) { case 0: //поиск groups_s if (c == '#') { s = 1; lexeme = ""; } else return null; break; case 1: //group_s if (isDigit(c)) { res.group_s += c; lexeme += c; } else if (c == ':') { s = 2; res.group = Integer.parseInt(lexeme); } else return null; break; case 2: //поиск filename if (c == ' ') { s = 3; } else return null; break; case 3: //filename if (c == ':') { s = 4; } else { res.file += c; } break; case 4: //поиск line if (c == ' ') { s = 5; lexeme = ""; } else return null; break; case 5: //line if (c == ' ') { if (!lexeme.equals("line")) return null; else { s = 6; lexeme = ""; } } else { lexeme += c; } break; case 6: //line number if (isDigit(c)) { lexeme += c; } else if (c == ']') { res.line = Integer.parseInt(lexeme); s = 7; } else return null; break; case 7: //Поиск value if (c == ':') { s = 8; } else return null; break; case 8: if (c == ' ') { s = 9; } else return null; break; case 9: //value res.value += c; break; } ; ++i; } //-- if (s != 9) return null; //-- return res; } public void readMessagesFromFileDump(File file, Vector messages) throws Exception { //Образец запакованного сообщения //ERROR - [#1020: red43.fdv: line 988]: Active DVM directives are not supported (turn on DVM-directive support option) Vector lines = new Vector<>(FileUtils.readLines(file)); if (!lines.isEmpty()) { for (int i = lines.size() - 1; i >= 0; --i) { String line = lines.get(i); if (line.startsWith("ERROR - ")) { MessageError message = unpackMessage(line); if (message != null) messages.add(message); //-- } else break; } } } protected void checkVersion(SapforVersion_json version, boolean isTransformation) throws Exception { db_project_info project = new db_project_info(); project.Home = new File(version.version); project.name = project.Home.getName(); project.description = version.description; project.languageName = LanguageName.fortran; project.creationDate = Utils.getDateNumber(); //-- Vector messages = new Vector<>(); //-- if (isTransformation) { File p_out = Paths.get(project.Home.getAbsolutePath(), Constants.data, "parse_out.txt").toFile(); File out = Paths.get(project.Home.getAbsolutePath(), Constants.data, "out.txt").toFile(); //-- if (p_out.exists()) { project.Log += (FileUtils.readFileToString(p_out)); readMessagesFromFileDump(p_out, messages); } if (out.exists()) { project.Log += "\n" + FileUtils.readFileToString(out); readMessagesFromFileDump(out, messages); } //-- } project.CreateVisualiserData(); //--- if (isTransformation && !messages.isEmpty()) { project.Open(); project.db.BeginTransaction(); // System.out.println("messages size=" + messages.size()); for (MessageError m : messages) { if (project.db.files.containsKey(m.file)) { DBProjectFile file = project.db.files.Data.get(m.file); file.CreateAndAddNewMessage(1, m.value, m.line, m.group); //update file project.db.Update(file); } } project.db.Commit(); project.db.Disconnect(); } } //-------------------------------------------------->> @Override protected void body() throws Exception { System.out.println(target.root + " " + Utils.Brackets(sapforConfiguration_json.flags));//!! for (PassCode_2021 code : sapforConfiguration_json.codes) { // System.out.println(code); //!! if (parse()) { if (code.equals(PassCode_2021.CreateParallelVariants)) variants(); else if (!transformation(code)) break; } else break; } //теперь строим деревья версий. //System.out.println("Построение дерева версий.."); checkVersion(new SapforVersion_json(target.root, "исходная"), true); for (SapforVersion_json version : target.versions) checkVersion(version, true); for (SapforVersion_json version : target.variants) checkVersion(version, false); //---->>>> //System.out.println("DONE"); } }