diff SMART/Java/PythonHelperReader.java @ 31:0ab839023fe4

Uploaded
author m-zytnicki
date Tue, 30 Apr 2013 14:33:21 -0400
parents 769e306b7933
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SMART/Java/PythonHelperReader.java	Tue Apr 30 14:33:21 2013 -0400
@@ -0,0 +1,336 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.io.File;
+import java.io.*;
+import java.util.regex.*;
+
+public class PythonHelperReader {
+
+  String         fileName;
+  Program        program;
+  BufferedReader reader;
+  String         message;
+
+  public PythonHelperReader(String fileName) {
+    this.fileName = fileName;  
+    this.reader   = reader;
+    this.message  = null;
+  }
+
+  public void setReader(BufferedReader reader) {
+    this.reader = reader;
+  }
+  
+  public void run() {
+    this.program                     = new Program();
+    boolean         inBeginning      = true;
+    boolean         inUsage          = false;
+    boolean         afterUsage       = false;
+    boolean         inDescription    = false;
+    boolean         afterDescription = false;
+    boolean         inOptions        = false;
+    boolean         inOptionBlank    = false;
+    boolean         inError          = false;
+    String          usage            = null;
+    String          description      = null;
+    String          option           = null;
+    Vector <String> options          = new Vector < String > ();
+    String[]        optionSplitted;
+
+    // Parse file
+    try {
+      String line = null;
+
+      while ((line = reader.readLine()) != null) {
+        line = line.trim();
+        if (line.startsWith("Traceback")) {
+          this.message     = "Problem with header of '" + this.fileName + "':\n" + line + "\n";
+          inError          = true;
+          inBeginning      = false;
+          inUsage          = false;
+          afterUsage       = false;
+          inDescription    = false;
+          afterDescription = false;
+          inOptions        = false;
+          inOptionBlank    = false;
+        }
+        else if (inError) {
+          this.message += line + "\n";
+        }
+        else if (inBeginning) {
+          if (line.startsWith("Usage:")) {
+            inUsage     = true;
+            inBeginning = false;
+            usage       = line;
+          }
+        }
+        else if (inUsage) {
+          if ("".equals(line)) {
+            inUsage    = false;
+            afterUsage = true;
+          }
+          else {
+            usage += " " + line;
+          }
+        }
+        else if (afterUsage) {
+          if (! "".equals(line)) {
+            description   = line;
+            afterUsage    = false;
+            inDescription = true;
+          }
+        }
+        else if (inDescription) {
+          if ("".equals(line)) {
+            inDescription    = false;
+            afterDescription = true;
+          }
+          else {
+            description += " " + line;
+          }
+        }
+        else if (afterDescription) {
+          if (! "".equals(line)) {
+            afterDescription = false;
+            inOptions        = true;
+          }
+        }
+        else if (inOptions) {
+          if ("".equals(line)) {
+            inOptions     = false;
+            inOptionBlank = true;
+          }
+          else {
+            if (option == null) {
+              option = line;
+            }
+            else {
+              if (line.charAt(0) == '-') {
+                options.add(option);
+                option = line;
+              }
+              else {
+                option += " " + line;
+              }
+            }
+          }
+        }
+        else if (inOptionBlank) {
+          if (! "".equals(line)) {
+            inOptionBlank = false;
+            inOptions     = true;
+          }
+        }
+        else {
+          this.message = "Something is wrong in the file '" + this.fileName + "'.\n";
+          return;
+        }
+      }
+
+      reader.close();
+    }
+    catch (FileNotFoundException e) {
+      this.message = "File " + this.fileName + " not found.\n";
+      return;
+    }
+    catch (IOException e) {
+      this.message = "IOException while reading file " + this.fileName;
+      return;
+    }
+
+    if (inError) {
+      return;
+    }
+
+    if (option != null) {
+      options.add(option);
+    }
+
+    HashMap < String, ProgramOption > identifierToOptions = new HashMap < String, ProgramOption > ();
+    HashMap < ProgramOption, String > associatedOption    = new HashMap < ProgramOption, String > ();
+
+    if (usage == null) {
+      this.message = "Cannot read the usage of file " + this.fileName + ".\n";
+      return;
+    }
+    program.setShortName(usage.split(" ")[1].trim());
+    program.setName(description.split(":")[0].trim());
+
+    Pattern pattern = Pattern.compile("\\[Category: .*\\]");
+    Matcher matcher = pattern.matcher(description);
+    if (matcher.find()) {
+      program.setSection(description.substring(matcher.start() + "[Category: ".length(), matcher.end() - 1));
+      program.setDescription(description.substring(0, matcher.start() - 1).trim());
+    }
+    else {
+      this.message = "Cannot find category in description '" + description + "' in file " + this.fileName + ".\n";
+      return;
+    }
+    for (int i = 0; i < options.size(); i++) {
+      option         = options.get(i).replace("\t", " ");
+      optionSplitted = option.split(" ");
+      option         = "";
+      for (int j = 3; j < optionSplitted.length; j++) {
+        option += optionSplitted[j] + " ";
+      }
+      
+      String identifier = optionSplitted[0].replace("-", "").replace(",", "");
+      // Skip -h and -v options
+      if (("h".equals(identifier)) || ("v".equals(identifier)))
+        continue;
+
+      ProgramOption programOption = new ProgramOption();
+      programOption.setIdentifier("-" + identifier);
+      int commentEnd = option.indexOf("[");
+      if (commentEnd == -1) {
+        this.message = "Do not understand option line '" + option + "' in file " + this.fileName + ".\n";
+        return;
+      }
+      programOption.setComment(option.substring(0, commentEnd).trim());
+      identifierToOptions.put(identifier, programOption);
+
+      pattern = Pattern.compile("\\[[^\\]]*\\]");
+      matcher = pattern.matcher(option);
+      while (matcher.find()) {
+        String inner = option.substring(matcher.start()+1, matcher.end()-1);
+        if (inner.contains(":")) {
+          String type  = inner.substring(0, inner.indexOf(":")).trim();
+          String value = inner.substring(inner.indexOf(":")+1).trim();
+          // Types of the options
+          if ("format".compareToIgnoreCase(type) == 0) {
+            String currentWord = "";
+            String rest        = "";
+            if (value.contains(" ")) {
+              int pos     = value.indexOf(" ");
+              currentWord = value.substring(0, pos);
+              rest        = value.substring(pos+1);
+            }
+            else {
+              currentWord = value;
+            }
+            // Output file type
+            if ("output".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setInput(false);
+              int pos     = rest.indexOf(" ");
+              currentWord = rest.substring(0, pos).trim();
+              rest        = rest.substring(pos+1).trim();
+            }
+            // File (input or output file)
+            if ("file".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setType("file");
+              // Format given by an associated option (to be found later)
+              if (rest.startsWith("in format given by ")) {
+                associatedOption.put(programOption, rest.substring(rest.indexOf("format given by ") + "format given by ".length() + 1).trim());
+              }
+              else {
+                if (! rest.startsWith("in ")) {
+                  this.message = "Descriptor " + option + " does not have a proper format.\n";
+                  return;
+                }
+                rest = rest.substring("in ".length());
+                int pos = rest.indexOf(" format");
+                if (pos == -1) {
+                  this.message = "Descriptor " + option + " does not have a proper format.\n";
+                  return;
+                }
+                programOption.setFormat(rest.substring(0, pos).trim().toLowerCase().split(" or "));
+              }
+            }
+            // Format type
+            else if (rest.endsWith("file format")) {
+              programOption.setFormat((currentWord + " " + rest.substring(0, rest.indexOf("file format"))).trim().toLowerCase().split(" or "));
+              programOption.setType("format");
+            }
+            // Choice type
+            else if ("choice".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setChoices(rest.replace("(", "").replace(")", "").split(", "));
+              programOption.setType("choice");
+            }
+            // Boolean type
+            else if ("bool".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setType("boolean");
+            }
+            // Other type
+            else {
+              if (currentWord == null) {
+                this.message = "Program '" + this.fileName + "' has a problem concerning the type of option '" + identifier + "'.\n";
+                return;
+              }
+              programOption.setType(currentWord);
+            }
+          }
+          // Default value
+          else if ("default".compareToIgnoreCase(type) == 0) {
+            programOption.setDefault(value);
+          }
+          else {
+            this.message = "Do not understand option descriptor '" + inner + "'.\n";
+            return;
+          }
+        }
+        else {
+          // Compulsory option
+          if ("compulsory".compareToIgnoreCase(inner) == 0) {
+            programOption.setCompulsory(true);
+          }
+          else {
+            this.message = "Do not understand option descriptor '" + inner + "'.\n";
+            return;
+          }
+        }
+      }
+      if (! programOption.checkSettings()) {
+        this.message = "Program '" + this.fileName + "' has a problem concerning option '" + identifier + "'.\n";
+        return;
+      }
+      program.addOption(programOption);
+    }
+
+    // Set associated option
+    Iterator it = associatedOption.keySet().iterator();
+    while (it.hasNext()) {
+      ProgramOption programOption = (ProgramOption) it.next();
+      programOption.setAssociatedOption(identifierToOptions.get(associatedOption.get(programOption)));
+    }
+  }
+
+  public String getMessage () {
+    return this.message;
+  }
+
+  public Program getProgram () {
+    return this.program;
+  }
+}
+
+