From d376760816ab9c650d7e344b58a0d167211155b3 Mon Sep 17 00:00:00 2001 From: Moncef STITI <moncef.stiti@etu.u-pec.fr> Date: Sun, 16 Mar 2025 17:14:50 +0100 Subject: [PATCH] Correction bug #2 --- src/fr/monlouyan/bakefile/BakefileParser.java | 117 ++++++++++++++---- src/fr/monlouyan/bakefile/Rule.java | 21 +++- 2 files changed, 110 insertions(+), 28 deletions(-) diff --git a/src/fr/monlouyan/bakefile/BakefileParser.java b/src/fr/monlouyan/bakefile/BakefileParser.java index b374a77..4c70fc9 100644 --- a/src/fr/monlouyan/bakefile/BakefileParser.java +++ b/src/fr/monlouyan/bakefile/BakefileParser.java @@ -28,7 +28,7 @@ public class BakefileParser { * Format : "nom1 nom2 nom3 : dépendance1 dépendance2" * La nouvelle regex gère plusieurs cibles séparées par des espaces */ - private static final Pattern TARGET_PATTERN = Pattern.compile("^([A-Za-z0-9_.\\/\\-\\$\\(\\)\\{\\}~]+(?:\\s+[A-Za-z0-9_.\\/\\-\\$\\(\\)\\{\\}~]+)*)\\s*:\\s*([^#]*?)\\s*(?:#.*)?$"); + private static final Pattern TARGET_PATTERN = Pattern.compile("^((?:\"[^\"]*\"|[A-Za-z0-9_.\\/\\-\\$\\(\\)\\{\\}~]+)(?:\\s+(?:\"[^\"]*\"|[A-Za-z0-9_.\\/\\-\\$\\(\\)\\{\\}~]+))*)\\s*:\\s*([^#]*?)\\s*(?:#.*)?$"); /** * Regex pour détecter les lignes de commande associées à une target. @@ -187,36 +187,105 @@ public class BakefileParser { * @param depStr Chaîne de dépendances * @return Liste de dépendances */ - private List<String> splitDependencies(String depStr) { - if (depStr == null || depStr.trim().isEmpty()) { - return new ArrayList<>(); - } - + private List<String> splitDependencies(String depStr) { + if (depStr == null || depStr.trim().isEmpty()) { + return new ArrayList<>(); + } + String cleanedStr = depStr.replaceAll("\\\\\\s*", " "); - - String resolvedStr = replaceVariables(cleanedStr.trim()); - return Arrays.stream(resolvedStr.split("\\s+")) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .collect(Collectors.toList()); - } + List<String> deps = new ArrayList<>(); + StringBuilder currentDep = new StringBuilder(); + boolean inQuotes = false; + + for (int i = 0; i < cleanedStr.length(); i++) { + char c = cleanedStr.charAt(i); + + if (c == '"') { + inQuotes = !inQuotes; + currentDep.append(c); + } else if (c == ' ' && !inQuotes) { + // Espace en dehors des guillemets, c'est un séparateur + if (currentDep.length() > 0) { + String dep = currentDep.toString().trim(); + if (!dep.isEmpty()) { + deps.add(dep); + } + currentDep = new StringBuilder(); + } + } else { + currentDep.append(c); + } + } + + // Ajouter la dernière dépendance s'il existe + if (currentDep.length() > 0) { + String dep = currentDep.toString().trim(); + if (!dep.isEmpty()) { + deps.add(dep); + } + } + + if (BakeCLI.isDebug()) { + System.out.println("Debug: Split dependencies: " + deps); + } + + // Appliquer replaceVariables à chaque dépendance + return deps.stream() + .map(this::replaceVariables) + .collect(Collectors.toList()); + } /** * Découper les cibles en une liste de chaînes. * @param targetStr Chaîne de cibles * @return Liste de cibles */ - private List<String> splitTargets(String targetStr) { - if (targetStr == null || targetStr.trim().isEmpty()) { - return new ArrayList<>(); - } - - String resolvedStr = replaceVariables(targetStr.trim()); - return Arrays.stream(resolvedStr.split("\\s+")) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .collect(Collectors.toList()); - } + private List<String> splitTargets(String targetStr) { + if (targetStr == null || targetStr.trim().isEmpty()) { + return new ArrayList<>(); + } + + List<String> targets = new ArrayList<>(); + StringBuilder currentTarget = new StringBuilder(); + boolean inQuotes = false; + + for (int i = 0; i < targetStr.length(); i++) { + char c = targetStr.charAt(i); + + if (c == '"') { + inQuotes = !inQuotes; + currentTarget.append(c); + } else if (c == ' ' && !inQuotes) { + // Espace en dehors des guillemets, c'est un séparateur + if (currentTarget.length() > 0) { + String target = currentTarget.toString().trim(); + if (!target.isEmpty()) { + targets.add(target); + } + currentTarget = new StringBuilder(); + } + } else { + currentTarget.append(c); + } + } + + // Ajouter le dernier target s'il existe + if (currentTarget.length() > 0) { + String target = currentTarget.toString().trim(); + if (!target.isEmpty()) { + targets.add(target); + } + } + + if (BakeCLI.isDebug()) { + System.out.println("Debug: Split targets: " + targets); + } + + // Appliquer replaceVariables à chaque cible + return targets.stream() + .map(this::replaceVariables) + .collect(Collectors.toList()); + } /** * Analyser le fichier Bakefile pour extraire les règles de build. diff --git a/src/fr/monlouyan/bakefile/Rule.java b/src/fr/monlouyan/bakefile/Rule.java index d22c015..f4c1d4a 100644 --- a/src/fr/monlouyan/bakefile/Rule.java +++ b/src/fr/monlouyan/bakefile/Rule.java @@ -96,7 +96,7 @@ public class Rule { for (String dep : dependencies) { System.out.println("Debug : Dependency: [" + dep + "]"); } - File targetFile = new File(name); + File targetFile = new File(cleanFileName(name)); System.out.println("Debug : Target file '" + name + "' exists: " + targetFile.exists()); } @@ -123,7 +123,7 @@ public class Rule { continue; } - File depFile = new File(dependency); + File depFile = new File(cleanFileName(dependency)); boolean hasRule = BakeEngine.hasRule(dependency); if (!depFile.exists() && !dependency.isEmpty() && !hasRule) { System.out.println("bake: *** No rule to make target `" + dependency + "', needed by `" + name + "'. Stop."); @@ -132,7 +132,7 @@ public class Rule { } // Si le fichier cible n'existe pas et qu'il y a des commandes, il doit être mis à jour - File targetFile = new File(name); + File targetFile = new File(cleanFileName(name)); if (!targetFile.exists() && !commands.isEmpty()) { if (BakeCLI.isDebug()) { System.out.println("Debug : Target file " + name + " does not exist and has commands, needs update"); @@ -178,7 +178,7 @@ public class Rule { continue; } - File depFile = new File(dependency); + File depFile = new File(cleanFileName(dependency)); if (!depFile.exists()) { continue; } @@ -220,4 +220,17 @@ public class Rule { return false; } + + /** + * Nettoie un nom de fichier en enlevant les guillemets si nécessaire. + * @param name Le nom du fichier à nettoyer + * @return Le nom du fichier sans guillemets + */ + private String cleanFileName(String name) { + // Enlever les guillemets au début et à la fin si présents + if (name.startsWith("\"") && name.endsWith("\"")) { + return name.substring(1, name.length() - 1); + } + return name; + } } \ No newline at end of file