package _VisualDVM; import Common.Passes.PassException; import Common.Utils.Index; import Common.Utils.StringTemplate; import Common.Utils.TextLog; import Common.Utils.Utils_; import Common.Visual.UI; import Common.Visual.Windows.Dialog.VFileChooser_; import _VisualDVM.GlobalData.Settings.SettingName; import _VisualDVM.GlobalData.Tasks.TaskState; import _VisualDVM.ProjectData.Files.DBProjectFile; import _VisualDVM.ProjectData.Project.db_project_info; import javafx.util.Pair; import org.apache.commons.io.FileUtils; import javax.swing.tree.DefaultMutableTreeNode; import java.io.*; import java.math.BigInteger; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.URL; import java.nio.charset.Charset; import java.nio.file.*; import java.security.MessageDigest; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.IntStream; public class Utils { public static boolean isLinuxSystemCommand(String text) { for (String command : Constants.linux_system_commands) { if (text.equalsIgnoreCase(command)) return true; } return false; } public static String MFVar(Object o) { return "$(" + o.toString() + ")"; } public static String ReadAllText(File file) { try { return new String(Files.readAllBytes(file.toPath())); } catch (Exception e) { Utils_.MainLog.PrintException(e); } return ""; } public static void CleanDirectory(File dir) { if (dir.exists() && dir.isDirectory()) { File[] files = dir.listFiles(); if (files != null) { for (File f : files) { try { Utils_.forceDeleteWithCheck(f); } catch (Exception e) { Utils_.MainLog.PrintException(e); } } } } } public static void WriteToFile(File f, String text) throws IOException { Files.write( f.toPath(), text.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); } // http://java-online.ru/blog-archive.xhtml public static void getFilesCountR(File dir, Index res) { for (File f : dir.listFiles()) { res.Inc(); if (f.isDirectory()) getFilesCountR(f, res); } } public static int getFilesCount(File dir) { Index res = new Index(); getFilesCountR(dir, res); return res.getValue(); } public static File CreateTempResourceFile(String res_name) throws Exception { URL u = (Utils.class.getResource("/files/" + res_name)); InputStream i = u.openStream(); Path p = Paths.get(Global.TempDirectory.getAbsolutePath(), Utils_.getDateName(res_name)); Files.copy(i, p, StandardCopyOption.REPLACE_EXISTING); return p.toFile(); } public static void CreateResourceFile(String res_name, File dst) throws Exception { URL u = (Utils.class.getResource("/files/" + res_name)); InputStream i = u.openStream(); Files.copy(i, dst.toPath(), StandardCopyOption.REPLACE_EXISTING); } //просто дать объект под файл с сгенерированным именем public static File CreateTempFile(String name, String text) throws IOException { File res = getTempFileName(name); WriteToFile(res, text); return res; } public static File CreateTempFile(String name, String ext, String text) throws IOException { File res = getTempFileName(name, ext); WriteToFile(res, text); return res; } public static File getTempFileName(String name, String ext) { return Paths.get(System.getProperty("user.dir"), "Temp", Utils_.getDateName(name) + (ext.isEmpty() ? "" : ("." + ext))).toFile(); } public static File getTempFileName(String name) { return getTempFileName(name, ""); } public static boolean isAnchestor(File child, File anchestor) { return child.getAbsolutePath().startsWith(anchestor.getAbsolutePath() + (Utils_.isWindows() ? "\\" : "/")); } //при условии что это точно его предок public static String getRelativeAddress(File file, File anchestor) { return file.getAbsolutePath().substring(anchestor.getAbsolutePath().length() + 1); } //для переименования/добавления новых файлов. public static boolean validateFileShortNewName(String name, TextLog Log) { boolean res = true; if (name.isEmpty()) { Log.Writeln_("Имя файла не может быть пустым"); res = false; } if (Utils_.ContainsCyrillic(name)) { Log.Writeln_("Имя файла не может содержать кириллицу"); res = false; } if (Utils_.ContainsForbiddenName(name)) { Log.Writeln_("Имя файла не может содержать запрещённых символов\n" + Utils_.printAllForbiddenCharacters()); res = false; } return res; } //корень сюда гарантированно не попадает. значит можно запрещать двоеточие. //идет по всем уровням файлов public static boolean validateProjectFile(File file, TextLog Log) { String name = file.getName(); if (Utils_.ContainsCyrillic(name) || Utils_.ContainsForbiddenName(name)) { Log.Writeln_(file.getAbsolutePath()); return false; } return true; } //входной параметр всегда папка. public static void validateProjectFolder_r(File dir, TextLog Log) { validateProjectFile(dir, Log); File[] files = dir.listFiles(); if (files != null) for (File file : files) { if (file.isDirectory()) validateProjectFolder_r(file, Log); else validateProjectFile(file, Log); } } public static boolean validateProjectFolder(File dir, TextLog Log) { TextLog files_list = new TextLog(); String[] filesLines = files_list.text.split("\n"); validateProjectFolder_r(dir, files_list); if (!files_list.isEmpty()) Log.Writeln_("Имена " + filesLines.length + " файлов/подпапок содержат запрещённые символы " + Utils_.printAllForbiddenCharacters() + "или кириллицу"); //нужно проверить корень на наличие хоть одной программы. return Log.isEmpty(); } public static void GetVertices(float R, float r, float x0, float y0, int n, float phi) { boolean inner = false; for (int i = 0; i < 2 * n; i++) { float rad = inner ? r : R; System.out.println("x=" + (x0 + rad * Math.cos(phi + Math.PI * i / n))); System.out.println("y=" + (y0 + rad * Math.sin(phi + Math.PI * i / n))); System.out.println("--"); inner = !inner; } } public static String md5Custom(String st) { MessageDigest messageDigest = null; byte[] digest = new byte[0]; try { messageDigest = MessageDigest.getInstance("MD5"); messageDigest.reset(); messageDigest.update(st.getBytes()); digest = messageDigest.digest(); } catch (Exception e) { // тут можно обработать ошибку // возникает она если в передаваемый алгоритм в getInstance(,,,) не существует Utils_.MainLog.PrintException(e); } BigInteger bigInt = new BigInteger(1, digest); String md5Hex = bigInt.toString(16); while (md5Hex.length() < 32) { md5Hex = "0" + md5Hex; } return md5Hex; } public static void renameSubdirs_r(DefaultMutableTreeNode node, File old_anchestor, File new_anchestor) { if (node.getUserObject() instanceof File) { File old_file = (File) node.getUserObject(); String relative_name = old_file.getAbsolutePath().substring(old_anchestor.getAbsolutePath().length() + 1); File new_file = Paths.get(new_anchestor.getAbsolutePath(), relative_name).toFile(); node.setUserObject(new_file); for (int i = 0; i < node.getChildCount(); ++i) { renameSubdirs_r((DefaultMutableTreeNode) node.getChildAt(i), old_anchestor, new_anchestor); } } } public static Socket createClientSocket(InetAddress address, int port, int timeout) throws Exception { Socket socket = new Socket(); socket.setSoTimeout(timeout); socket.connect(new InetSocketAddress(address, port), timeout); return socket; } public static void CreateResourceFile(File dst) throws Exception { URL u = (Utils.class.getResource("/files/" + dst.getName())); InputStream i = u.openStream(); Files.copy(i, dst.toPath(), StandardCopyOption.REPLACE_EXISTING); } public static void getFilesByExtensions_r(File dir, Vector res, String... extensions) { File[] files = dir.listFiles(); if (files != null) { for (File file : files) { if (file.isFile()) { String file_extension = Utils_.getExtension(file); for (String ext : extensions) { if (file_extension.equalsIgnoreCase(ext)) { res.add(file); } } } if (file.isDirectory()) getFilesByExtensions_r(file, res, extensions); } } } //----->> public static void deleteFilesByExtensions(File dir, String... extensions) throws Exception { Vector res = new Vector<>(); Utils.getFilesByExtensions_r(dir, res, extensions); for (File src : res) Utils_.forceDeleteWithCheck(src); } //----->> //--процессы-------------------------------------------------->>>>> // public static Process startScript(File scriptDirectory, File targetDirectory, String name, String scriptText, Map envs) throws Exception { //-> File scriptFile = createScript(scriptDirectory, targetDirectory, name, scriptText); ProcessBuilder procBuilder = new ProcessBuilder(scriptFile.getAbsolutePath()); procBuilder.directory(scriptDirectory); procBuilder.redirectErrorStream(true); if (envs != null) { for (String envName : envs.keySet()) { procBuilder.environment().put(envName, envs.get(envName)); } } return procBuilder.start(); } public static Process startScript(File scriptDirectory, File targetDirectory, String name, String scriptText) throws Exception { return startScript(scriptDirectory, targetDirectory, name, scriptText, null); } public static File createScript(File scriptDirectory, File targetDirectory, String name, String scriptText) throws Exception { //-> File scriptFile = Paths.get(scriptDirectory.getAbsolutePath(), name + (Utils_.isWindows() ? ".bat" : "")).toFile(); FileUtils.write(scriptFile, "cd " + Utils_.DQuotes(targetDirectory.getAbsolutePath()) + "\n" + scriptText); if (!scriptFile.setExecutable(true)) throw new PassException("Не удалось создать исполняемый файл для скрипта"); return scriptFile; } // // public static String readLine(Process process) throws Exception { InputStream stdout = process.getInputStream(); InputStreamReader isrStdout = new InputStreamReader(stdout); BufferedReader brStdout = new BufferedReader(isrStdout); String line = brStdout.readLine(); return line; } public static Vector readAllLines(Process process) throws Exception { Vector output = new Vector<>(); InputStream stdout = process.getInputStream(); InputStreamReader isrStdout = new InputStreamReader(stdout); BufferedReader brStdout = new BufferedReader(isrStdout); String line; while ((line = brStdout.readLine()) != null) { output.add(line); } return output; } public static String readAllOutput(Process process) throws Exception { return String.join("\n", readAllLines(process)); } // public static String extractHeaderName(String line) { String tline = line.trim().toLowerCase(); if (tline.startsWith("include")) { String[] data = tline.split("'"); return data.length > 1 ? data[1] : null; } return null; } public static String getRelativeName(File dir, File file) { return file.getAbsolutePath().startsWith(dir.getAbsolutePath()) ? file.getAbsolutePath().substring(dir.getAbsolutePath().length() + 1).replace('/', '\\') : file.getAbsolutePath() ; } public static boolean containsLine(Vector list, String line, int max_index) { int last_index = -1; for (int i = 0; i < list.size(); ++i) if (list.get(i).equals(line)) last_index = i; return (last_index >= max_index); } public static String compareTexts(String master, String slave) { Vector lines = new Vector<>(Arrays.asList(master.split("\n"))); Vector slavelines = new Vector<>(Arrays.asList(slave.split("\n"))); Vector t2 = new Vector<>(); int old_j = 0; int j = 0; for (int i = 0; i < lines.size(); ++i) { if (containsLine(slavelines, lines.get(i), old_j)) { for (int k = old_j; k < slavelines.size(); ++k) { j = k; if (lines.get(i).equals(slavelines.get(k))) { j++; t2.add(slavelines.get(k)); break; } else t2.add("+ " + slavelines.get(k)); } old_j = j; } else { //строки гарантированно нет. t2.add("- " + lines.get(i)); } } //теперь граничное условие. если первый файл кончился а второй нет, его остаток это добавление. for (int i = j; i < slavelines.size(); ++i) t2.add("+ " + slavelines.get(i)); return String.join("\n", t2); } public static int getHalfKernels() { int countCores = 1; if (Runtime.getRuntime().availableProcessors() > 1) countCores = Runtime.getRuntime().availableProcessors() / 2; return countCores; } public static int getMaxKernels() { return Math.max(2, Runtime.getRuntime().availableProcessors()); } public static int getMatrixProcessors(String matrix) { if (matrix.trim().isEmpty()) return 1; String[] data = matrix.split(" "); int res = 1; for (String d : data) res *= Integer.parseInt(d); return res; } public static int getCTestMaxDim(File test) { int fileMax = 0; final String prefix = "#pragma dvm array distribute"; int n = 0; try { for (String line : FileUtils.readLines(test, Charset.defaultCharset())) { // #pragma dvm array distribute[block][block], не важно String packedLine = Utils_.removeCharacters(Utils_.removeRedundantSpaces(line).toLowerCase(), "\n", "\r", "\t"); if (packedLine.startsWith(prefix)) { packedLine = packedLine.substring(prefix.length()); boolean bracketOpen = false; int pragmaMax = 0; String distr = ""; for (int i = packedLine.indexOf('['); i < packedLine.length(); ++i) { char c = packedLine.charAt(i); if (bracketOpen) { if (c == ']') { bracketOpen = false; if (distr.equals("block")) pragmaMax++; distr = ""; } else { distr += c; } } else { if (c == '[') { bracketOpen = true; } else { break; } } } fileMax = Math.max(fileMax, pragmaMax); } ++n; } } catch (Exception ex) { ex.printStackTrace(); } return fileMax; } public static int getCProjectMaxDim(db_project_info project) { int res = 0; for (DBProjectFile file : project.db.files.Data.values()) { if (file.isActiveProgram()) res = Math.max(res, getCTestMaxDim(file.file)); } return res; } public static boolean isTimeout(long startDate, long maxtime_sec) { Date now = new Date(); long delta = (now.getTime() - startDate) / 1000; return (delta > maxtime_sec); } //https://translated.turbopages.org/proxy_u/en-ru.ru.596e2df7-62fd38bb-6b4aad49-74722d776562/https/stackoverflow.com/questions/34658054/finding-whole-word-only-in-java-string-search public static long findInFile(String keyword_in, boolean registerOn, boolean wholeWord, File file) { if (keyword_in.isEmpty()) return 0; long res = 0; try { String text = FileUtils.readFileToString(file); String keyword = keyword_in; //-->> if (!registerOn) { text = text.toUpperCase(); keyword = keyword.toUpperCase(); } String regex = wholeWord ? "\\b" + keyword + "\\b" : keyword; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(text); while (matcher.find()) res++; } catch (Exception e) { e.printStackTrace(); } return res; } public static void addEmptyLines(Vector lines, int num) { IntStream.range(0, num).mapToObj(i -> "").forEach(lines::add); } protected static boolean isSource(File file) { if (file.isFile()) { String extension = Utils_.getExtension(file).toLowerCase(); switch (extension) { case "f": case "fdv": case "for": case "f77": case "f90": // case "fh": case "c": case "cdv": case "cpp": // case "h": return true; } } return false; } public static boolean containsSource(File folder, boolean question) { File visualiserData = new File(folder, Constants.data); if (visualiserData.exists()) { return true; } //есть папка с данными, значит его уже открывали, все хорошо. File[] files = folder.listFiles(); Vector sources = new Vector<>(); if (files != null) { for (File file : files) { if (isSource(file)) { sources.add(file); } } } if (sources.isEmpty()) { if (question) return UI.Question("Папка " + Utils_.Brackets(folder.getName()) + "\n" + "не содержит ни одного файла, распознанного как поддерживаемый код\n" + "Всё равно открыть её как проект"); else return false; } else return true; } public static void Kill(String PID, boolean force) { if (!PID.isEmpty()) { String killCommand = force ? Utils_.isWindows() ? "taskkill /PID " + Utils_.DQuotes(PID) + " /F /T" : "kill -9 " + Utils_.DQuotes(PID) : Utils_.isWindows() ? "taskkill /PID " + Utils_.DQuotes(PID) : "kill -2 " + Utils_.DQuotes(PID); System.out.println(killCommand); try { Process killer = Utils.startScript(Global.TempDirectory, Global.TempDirectory, "killer", killCommand); killer.waitFor(); System.out.println(Utils.readAllOutput(killer)); } catch (Exception ex) { ex.printStackTrace(); } } } public static boolean isFunctionName(String name) { if (name.isEmpty()) return false; char[] letters = name.toCharArray(); if (!(Utils_.isEnglishLetter(letters[0]) || letters[0] == '_')) { return false; } //--- for (int i = 1; i < letters.length; ++i) { if (!(Utils_.isEnglishLetter(letters[i]) || letters[i] == '_' || Utils_.isIntegerValue(String.valueOf(letters[i])))) { return false; } } return true; } public static void keepNewFiles(File directory, int count) throws Exception { if (count > 0) { File[] old_ = directory.listFiles(pathname -> pathname.isFile()); if (old_ != null) { Vector old = new Vector<>(); Collections.addAll(old, old_); old.sort((o1, o2) -> Long.compare(o2.lastModified(), o1.lastModified())); for (int i = count - 1; i < old.size(); ++i) { File file = old.get(i); FileUtils.forceDelete(file); } } } } public static boolean isParallelVersionName(String name) { char[] chars = name.toLowerCase().toCharArray(); if ((chars.length > 1) && (chars[0] == 'p')) { for (int i = 1; i < chars.length; ++i) { if (!Character.isDigit(chars[i])) { return false; } } return true; } return false; } public static boolean isCrushedLine(String line) { String l_line = line.toLowerCase(); for (String crushed : Constants.crushed_cases) if (l_line.contains(crushed)) return true; return false; } public static boolean isCrushed(List output_lines, List errors_lines) { return output_lines.stream().anyMatch(Utils::isCrushedLine) || errors_lines.stream().anyMatch(Utils::isCrushedLine); } public static Pair analyzeCorrectness(List lines) { int complete = 0; int errors = 0; int total = 0; int starts = 0; int ends = 0; for (String s : lines) { String line = s.toUpperCase(); if (line.contains("COMPLETE")) { complete++; total++; } else if (line.contains("ERROR")) { errors++; total++; } else if (line.contains("START")) { starts++; } else if (line.contains("END")) { ends++; } } TaskState state = TaskState.Finished; if (starts != ends) { state = TaskState.WrongTestFormat; } else if (errors > 0) { state = TaskState.DoneWithErrors; } else { state = TaskState.Done; } return new Pair<>(state, (int) ((((double) complete) / total) * 100)); } public static Pair analyzePerformance(List lines) { StringTemplate stringTemplate = new StringTemplate("Verification =", ""); for (String line : lines) { String param = stringTemplate.check_and_get_param(line); if (param != null) { switch (param) { case "SUCCESSFUL": return new Pair<>(TaskState.Done, 100); case "UNSUCCESSFUL": return new Pair<>(TaskState.DoneWithErrors, 0); default: break; } } } return new Pair<>(TaskState.WrongTestFormat, 0); } public static double parseCleanTime(String output) { double res = 0.0; StringTemplate template = new StringTemplate("Time in seconds =", ""); String p = template.check_and_get_param(output); try { if (p != null) res = Double.parseDouble(p); } catch (Exception ex) { Utils_.MainLog.PrintException(ex); } return res; } public static void RestoreSelectedDirectory(VFileChooser_ directoryChooser) { String last_dir_home = (Global.mainModule.getDb()).settings.get(SettingName.ProjectsSearchDirectory).Value; if (!last_dir_home.isEmpty()) directoryChooser.SetCurrentDirectory(last_dir_home); } public static void ClearProjectData(File project_home) throws Exception { Utils.deleteFilesByExtensions(project_home, "dep", "proj"); File project_data = new File(project_home, Constants.data); if (project_data.exists()) FileUtils.forceDelete(project_data); } //-- public static boolean isVersion(File directory) throws Exception { return new File(directory, Constants.data).exists(); } public static boolean checkFileCreation(File file) { for (int i = 1; i <= 10; ++i) { if (file.exists()) return true; else Utils_.sleep(1000); } return false; } public static void createEmptyFile(String name) { File file = new File(name); try { FileUtils.writeStringToFile(file, ""); } catch (Exception ex) { ex.printStackTrace(); } } public static Pair, Vector> getFortranLines(String text) { Vector lines = new Vector<>(); Vector visible_lines = new Vector<>(); //1.прочитать весь текст. char[] chars = text.toCharArray(); //по символам получить строки. char c = 0; //текущий символ int i = 0; //индекс текущего символа. StringBuilder line = new StringBuilder(); //текущая строка StringBuilder v_line = new StringBuilder(); //текущая строка while (i < chars.length) { c = chars[i]; //System.out.print("`"+c+"`"); ++i; switch (c) { case '\r': //возврат каретки, игнор break; case ' ': case '\t': if ((Global.mainModule.getDb()).settings.get(SettingName.SpacesOn).toBoolean()) line.append(c); v_line.append(c); break; case '\n': //конец строки if ((Global.mainModule.getDb()).settings.get(SettingName.FortranWrapsOn).toBoolean()) { //оракул. лезем в начало следующей строки //и анализируем первые 5 символов boolean hasWrap = false; int wi; //------ //с нуля потому что и уже увеличено. for (int j = 0; (j < 6) && ((wi = i + j) < chars.length); ++j) { char s = chars[wi]; if ((j == 0) && ((s == 'c') || (s == 'C') || (s == '!'))) { break; } if ((j > 0) && (j < 5) && (s == '!')) { break; } if ((j == 5) && (s != ' ')) { hasWrap = true; i = wi + 1; break; } } //----- if (hasWrap) break; } //добавление строки в результат. if ((line.length() > 0) || (Global.mainModule.getDb()).settings.get(SettingName.EmptyLinesOn).toBoolean() // Global.db.settings.get(SettingName.SpacesOn).toBoolean() ) { lines.add(line.toString()); visible_lines.add(v_line.toString()); } //сброс line = new StringBuilder(); v_line = new StringBuilder(); break; default: line.append(c); v_line.append(c); break; } } if ((i > 0) && (c != '\n')) { //строка оборвалась на EOF //добавление строки в результат. if ((line.length() > 0) || (Global.mainModule.getDb()).settings.get(SettingName.EmptyLinesOn).toBoolean() // && Global.db.settings.get(SettingName.SpacesOn).toBoolean() ) { lines.add(line.toString()); visible_lines.add(v_line.toString()); } } return new Pair<>(lines, visible_lines); } public static boolean CompareLines(String line1_raw, String line2_raw) { String line1 = line1_raw; String line2 = line2_raw; if (!(Global.mainModule.getDb()).settings.get(SettingName.RegisterOn).toBoolean()) { line1 = line1.toUpperCase(); line2 = line2.toUpperCase(); } if (!(Global.mainModule.getDb()).settings.get(SettingName.SpacesOn).toBoolean()) { line1 = Utils_.removeCharacters(line1, " ", "\t"); line2 = Utils_.removeCharacters(line2, " ", "\t"); } return line1.equals(line2); } public static boolean Contains(Vector list, String line, int max_index) { int last_index = -1; for (int i = 0; i < list.size(); ++i) if (CompareLines(list.get(i), line)) last_index = i; return (last_index >= max_index); } public static boolean compareFortranTexts(String text1, String text2) { Pair, Vector> p1 = getFortranLines(text1); Pair, Vector> p2 = getFortranLines(text2); Vector lines1 = p1.getKey(); Vector lines2 = p2.getKey(); if (lines1.size() != lines2.size()) return false; for (int i = 0; i < lines1.size(); ++i) { if (!CompareLines(lines1.get(i), lines2.get(i))) return false; } return true; } //-- private static void get_newest_file_date_r(File dir, Vector dates) { Vector files = new Vector(Arrays.asList(dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isFile(); } }))); if (!files.isEmpty()) { files.sort(new Comparator() { @Override public int compare(File o1, File o2) { return Long.compare(o1.lastModified(), o2.lastModified()); } }.reversed()); dates.add(files.firstElement().lastModified()); } //-- Vector subdirs = new Vector(Arrays.asList(dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isDirectory(); } }))); if (!subdirs.isEmpty()) { for (File subdir : subdirs) get_newest_file_date_r(subdir, dates); } } public static long getNewestFileDate(File dir) { Vector dates = new Vector<>(); get_newest_file_date_r(dir, dates); Collections.sort(dates); if (dates.isEmpty()) { dates.add(dir.lastModified()); } System.out.println(new Date(dates.lastElement())); return dates.firstElement(); } public static void addDefaultMails(Vector mails) { if (!mails.contains(Constants.MailAddress)) mails.add(Constants.MailAddress); for (String mail : Constants.admins_mails) { if (!mails.contains(mail)) mails.add(mail); } } }