]> Dogcows Code - chaz/vimcoder/commitdiff
improved C++ driver template
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Fri, 12 Nov 2010 05:23:36 +0000 (22:23 -0700)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Fri, 12 Nov 2010 05:23:36 +0000 (22:23 -0700)
fixes #3

src/com/dogcows/Editor.java
src/com/dogcows/Utility.java [moved from src/com/dogcows/Utilities.java with 92% similarity]
src/com/dogcows/VimCoder.java
src/com/dogcows/resources/C++Driver
src/com/dogcows/resources/C++Template
src/com/dogcows/resources/C++Test [deleted file]

index dda5481fe2971f2173044d0758b8fdf887900adc..ddb7ccfe69043010dac3787b77a3bb15297efc4d 100644 (file)
@@ -7,8 +7,7 @@ import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 import com.topcoder.client.contestant.ProblemComponentModel;
 import com.topcoder.shared.language.Language;
@@ -24,7 +23,6 @@ public class Editor
 {
     private String  id;
     private String  name;
-    
     private File    sourceFile;
     private File    directory;
     
@@ -44,8 +42,8 @@ public class Editor
                   Language language,
                   Renderer renderer) throws IOException
     {
-        this.id     = String.valueOf(component.getProblem().getProblemID());
-        this.name   = component.getClassName();
+        this.id = String.valueOf(component.getProblem().getProblemID());
+        this.name = component.getClassName();
         
         File topDir = new File(System.getProperty("user.home"), ".vimcoder");
         if (!topDir.isDirectory())
@@ -63,13 +61,18 @@ public class Editor
         String ext  = languageExtension.get(lang);
         
         HashMap<String,String> terms = new HashMap<String,String>();
-        terms.put("RETURNTYPE", component.getReturnType().getDescriptor(language));
-        terms.put("CLASSNAME",  component.getClassName());
+        terms.put("RETURNTYPE", component.getReturnType().getDescriptor(language).replaceAll("\\s+", ""));
+        terms.put("CLASSNAME",  name);
         terms.put("METHODNAME", component.getMethodName());
         terms.put("METHODPARAMS", getMethodParams(component.getParamTypes(),
                                                   component.getParamNames(),
                                                   language));
-        terms.put("METHODPARAMNAMES", Utilities.join(component.getParamNames(), ", "));
+        terms.put("METHODPARAMNAMES", Utility.join(component.getParamNames(), ", "));
+        terms.put("METHODPARAMSTREAMIN", Utility.join(component.getParamNames(), " >> "));
+        terms.put("METHODPARAMSTREAMOUT", Utility.join(component.getParamNames(), " << "));
+        terms.put("METHODPARAMDECLARES", getMethodParamDeclarations(component.getParamTypes(),
+                                                                    component.getParamNames(),
+                                                                    language));
         
         File problemFile = new File(directory, "Problem.html");
         if (!problemFile.canRead())
@@ -85,36 +88,41 @@ public class Editor
             writer.close();
         }
         
-        sourceFile = new File(directory, terms.get("CLASSNAME") + "." + ext);
+        sourceFile = new File(directory, name + "." + ext);
         if (!sourceFile.canRead())
         {
-            String text = Utilities.expandTemplate(Utilities.readResource(lang + "Template"),
+            String text = Utility.expandTemplate(Utility.readResource(lang + "Template"),
                                          terms);
             FileWriter writer = new FileWriter(sourceFile);
             writer.write(text);
             writer.close();
         }
 
-        File driverFile = new File(directory, "driver" + "." + ext);
-        if (!driverFile.canRead())
+        File testcaseFile = new File(directory, "testcases.txt");
+        if (!testcaseFile.canRead())
         {
-            StringBuilder testCases = new StringBuilder();
+            StringBuilder text = new StringBuilder();
             if (component.hasTestCases())
             {
-                HashMap<String,String> testTerms = new HashMap<String,String>();
-                testTerms.putAll(terms);
-                String template = Utilities.readResource(lang + "Test");
                 for (TestCase testCase : component.getTestCases())
                 {
-                    testTerms.put("TESTOUTPUT", "\"" + Utilities.quote(testCase.getOutput()) + "\"");
-                    testTerms.put("TESTINPUTS", Utilities.join(testCase.getInput(), ", "));
-                    testCases.append(Utilities.expandTemplate(template, testTerms));
+                    text.append(testCase.getOutput() + System.getProperty("line.separator"));
+                    for (String input : testCase.getInput())
+                    {
+                        text.append(input + System.getProperty("line.separator"));
+                    }
                 }
             }
-            terms.put("TESTCASES", testCases.toString());
-            
-            String text = Utilities.expandTemplate(Utilities.readResource(lang + "Driver"),
-                                         terms);
+            FileWriter writer = new FileWriter(testcaseFile);
+            writer.write(text.toString());
+            writer.close();
+        }
+        
+        File driverFile = new File(directory, "driver." + ext);
+        if (!driverFile.canRead())
+        {
+            String text = Utility.expandTemplate(Utility.readResource(lang + "Driver"),
+                                                 terms);
             FileWriter writer = new FileWriter(driverFile);
             writer.write(text);
             writer.close();
@@ -122,15 +130,15 @@ public class Editor
         
         File makeFile = new File(directory, "Makefile");
         {
-            String text = Utilities.expandTemplate(Utilities.readResource(lang + "Makefile"),
+            String text = Utility.expandTemplate(Utility.readResource(lang + "Makefile"),
                                          terms);
             FileWriter writer = new FileWriter(makeFile);
             writer.write(text);
             writer.close();
         }
     }
-    
-    public void setSource(String source) throws IOException
+
+    public void setSource(String source) throws Exception
     {
         FileWriter writer = new FileWriter(new File(directory, name));
         writer.write(source);
@@ -140,40 +148,63 @@ public class Editor
 
     public String getSource() throws IOException
     {
-        return Utilities.readFile(sourceFile) + "\n// Edited by " + VimCoder.version + "\n// " + VimCoder.website + "\n\n";
+        return Utility.readFile(sourceFile) + "\n// Edited by " + VimCoder.version + "\n// " + VimCoder.website + "\n\n";
     }
     
     
-    private boolean doVimCommand(String command, String argument)
+    private void doVimCommand(String command, String argument) throws Exception
     {
         String[] arguments = {argument};
-        return doVimCommand(command, arguments);
+        doVimCommand(command, arguments);
     }
     
-    private boolean doVimCommand(String command, String[] arguments)
+    private void doVimCommand(String command, String[] arguments) throws Exception
     {
-        try
+        String[] exec = {"gvim", "--servername", "VimCoder" + id,
+                         command};
+        exec = Utility.concat(exec, arguments);
+        Process child = Runtime.getRuntime().exec(exec, null, directory);
+        
+        long expire = System.currentTimeMillis() + 500;
+        while (System.currentTimeMillis() < expire)
         {
-            String[] exec = {"gvim", "--servername", "VimCoder" + id,
-                             command};
-            exec = Utilities.concat(exec, arguments);
-            Runtime.getRuntime().exec(exec, null, directory);
+            try
+            {
+                int exitCode = child.exitValue();
+                if (exitCode != 0) throw new Exception("Vim process returned exit code " + exitCode + ".");
+                break;
+            }
+            catch (IllegalThreadStateException exception)
+            {
+            }
+            Thread.yield();
         }
-        catch (IOException exception)
+    }
+    
+    private String getMethodParams(DataType[] types,
+                                   String[] names,
+                                   Language language)
+    {
+        StringBuilder text = new StringBuilder();
+        
+        text.append(types[0].getDescriptor(language).replaceAll("\\s+", "") + " " + names[0]);
+        for (int i = 1; i < names.length; ++i)
         {
-            System.out.println("Failed to launch external vim process.  :-(");
+            text.append(", " + types[i].getDescriptor(language).replaceAll("\\s+", "") + " " + names[i]);
         }
-        return false;
+        
+        return text.toString();
     }
     
-    private String getMethodParams(DataType[] types, String[] names, Language language)
+    private String getMethodParamDeclarations (DataType[] types,
+                                               String[] names,
+                                               Language language)
     {
         StringBuilder text = new StringBuilder();
         
-        text.append(types[0].getDescriptor(language) + " " + names[0]);
-        for (int i = 1; i < names.length; ++i)
+        for (int i = 0; i < names.length; ++i)
         {
-            text.append(", " + types[i].getDescriptor(language) + " " + names[i]);
+            text.append(types[i].getDescriptor(language).replaceAll("\\s+", "") + "\t" + names[i] + ";" + System.getProperty("line.separator"));
         }
         
         return text.toString();
similarity index 92%
rename from src/com/dogcows/Utilities.java
rename to src/com/dogcows/Utility.java
index 7dddd1f111e492611db572c721d5306d16f946e9..9b4c7cc776cbeb08dc86e986440e344cf0401143 100644 (file)
@@ -9,7 +9,7 @@ import java.util.Map;
  * @author Charles McGarvey
  *
  */
-public abstract class Utilities
+public abstract class Utility
 {
 
     public static <T> T[] concat(T[] a, T[] b)
@@ -61,7 +61,7 @@ public abstract class Utilities
     {
         StringBuilder text = new StringBuilder();
         
-        InputStream stream = Utilities.class.getResourceAsStream("resources/" + path);
+        InputStream stream = Utility.class.getResourceAsStream("resources/" + path);
         if (stream != null)
         {
             try
@@ -88,8 +88,9 @@ public abstract class Utilities
         for (String key : terms.keySet())
         {
             text = text.replaceAll("\\$" + key + "\\$",
-                                   Utilities.quote(terms.get(key)));
+                                   Utility.quote(terms.get(key)));
         }
         return text;
     }
 }
+
index 5f69aaa75bd5c8a22009a7fa5644ee5bc169b5e5..1fb9bab8e774debc5ee7f753213b59a5217dc05a 100644 (file)
@@ -48,6 +48,7 @@ public class VimCoder
     
     public void startUsing()
     {
+        System.out.println("startUsing");
         Runnable task = new Runnable()
         {
             public void run()
@@ -67,39 +68,43 @@ public class VimCoder
     
     public void stopUsing()
     {
+        System.out.println("stopUsing");
         editor = null;
     }
     
     public JPanel getEditorPanel()
     {
+        System.out.println("getEditorPanel");
         return panel;
     }
    
-    public String getSource() throws IOException
+    public String getSource() throws Exception
     {
+        System.out.println("getSource");
         try
         {
             String source = editor.getSource();
             logInfo("Source code uploaded to server.");
             return source;
         }
-        catch (IOException exception)
+        catch (Exception exception)
         {
-            logError("Failed to open source file for reading.");
+            logError("Failed to get source code: " + exception.getLocalizedMessage());
             throw exception;
         }
     }
    
     public void setSource(String source)
     {
+        System.out.println("setSource: " + source);
         try
         {
             editor.setSource(source);
             logInfo("Source code downloaded from server.");
         }
-        catch (IOException exception)
+        catch (Exception exception)
         {
-            logError("Failed to save the source given by the server.");
+            logError("Failed to save the source given by the server: " + exception.getLocalizedMessage());
             return;
         }
     }
@@ -108,13 +113,14 @@ public class VimCoder
                                     Language language,
                                     Renderer renderer)
     {
+        System.out.println("setProblemComponent");
         try
         {
             editor = new Editor(component, language, renderer);
         }
-        catch (IOException exception)
+        catch (Exception exception)
         {
-            logError("An error occured while loading the problem.");
+            logError("An error occured while loading the problem: " + exception.getLocalizedMessage());
         }
     }
 
@@ -141,17 +147,17 @@ public class VimCoder
     
     private void logInfo(String what)
     {
-        log(" INFO: " + what + "\n");
+        log(" INFO: " + what + System.getProperty("line.separator"));
     }
     
     private void logWarning(String what)
     {
-        log(" WARN: " + what + "\n");
+        log(" WARN: " + what + System.getProperty("line.separator"));
     }
     
     private void logError(String what)
     {
-        log("ERROR: " + what + "\n");
+        log("ERROR: " + what + System.getProperty("line.separator"));
     }
     
     
index 9f25901fbdc34f972dc761abade4a17df0a0a704..718ced40bbce7d119631781e0779d426ace63ded 100644 (file)
@@ -1,14 +1,18 @@
 
 #include "$CLASSNAME$.cc"
 
+#include <cstdlib>
+#include <fstream>
 #include <iostream>
 #include <sstream>
+#include <string>
 #include <sys/time.h>
+#include <vector>
 
-static bool            __exit_on_fail = false;
-static int             __pass = 0;
-static int             __fail = 0;
-static double  __time = 0.0;
+using namespace std;
+
+
+static double __time = 0.0;
 
 static void __timer_start()
 {
@@ -26,77 +30,131 @@ static double __timer_stop()
        return __time - start;
 }
 
-template <class T>
-std::string __encode(const T& in)
-{
-       std::ostringstream s;
-       s << in;
-       return s.str();
-}
 
-std::string __encode(const std::string& in)
+std::ostream& operator << (std::ostream& out, const std::string& str)
 {
-       std::ostringstream s;
-       s << '"' << in << '"';
-       return s.str();
+       out << '"' << str.c_str() << '"';
+       return out;
 }
 
 template <class T>
-std::string __join(const std::vector<T>& in, const std::string& glue)
+std::ostream& operator << (std::ostream& out, const std::vector<T>& vec)
 {
-       if (in.size() == 0) return "";
-       std::ostringstream s;
-       s << __encode(in[0]);
-       for (size_t i = 1; i < in.size(); ++i) s << glue << __encode(in[i]);
-       return s.str();
+       out << '{';
+       if (0 < vec.size())
+       {
+               out << vec[0];
+               for (size_t i = 1; i < vec.size(); ++i) out << ", " << vec[i];
+       }
+       out << '}';
+       return out;
 }
 
-template <class T>
-std::string __encode(const std::vector<T>& in)
+std::istream& operator >> (std::istream& in, std::string& str)
 {
-       std::ostringstream s;
-       s << "{ " << __join(in, ",  ") << " }";
-       return s.str();
+       while (in.good() && std::isspace(in.peek())) in.get();
+
+       int c;
+       if (in.good() && (c = in.get()) == '"')
+       {
+               std::ostringstream s;
+               while (in.good() && (c = in.get()) != '"')
+               {
+                       s.put(char(c));
+               }
+               str = s.str();
+       }
+       else
+       {
+               in.putback(c);
+       }
+
+       return in;
 }
 
-void __do_test(const std::string& expected, $METHODPARAMS$)
+template <class T>
+std::istream& operator >> (std::istream& in, std::vector<T>& vec)
 {
-       static int testNum = 0;
-       std::cout << "----------------------------------------" << std::endl
-                         << "Test " << testNum++ << ": ";
+       while (in.good() && std::isspace(in.peek())) in.get();
 
-       __timer_start();
-       
-       $CLASSNAME$ object;
-       $RETURNTYPE$ ret = object.$METHODNAME$($METHODPARAMNAMES$);
-       
-       double t = __timer_stop();
-       
-       std::string actual = __encode(ret);
-       if (actual == expected)
+       int c;
+       if (in.good() && (c = in.get()) == '{')
        {
-               std::cout << "[PASS] in " << t << " seconds." << std::endl;
-               ++__pass;
+               while (in.good() && std::isspace(in.peek())) in.get();
+               T t;
+               vec.clear();
+               while (in.good() && (c = in.get()) != '}')
+               {
+                       if (c != ',') in.putback(c);
+                       in >> t;
+                       vec.push_back(t);
+                       while (in.good() && std::isspace(in.peek())) in.get();
+               }
+
        }
        else
        {
-               std::cout << "[FAIL] in " << t << " seconds." << std::endl
-                                 << "   Actual: " << actual << std::endl
-                                 << " Expected: " << expected << std::endl;
-               ++__fail;
-               if (__exit_on_fail) exit(1);
+               in.putback(c);
        }
+
+       return in;
 }
 
+
 int main(int argc, char* argv[])
 {
+       bool    __exit_on_fail = false;
+       int             __pass = 0;
+       int             __fail = 0;
+       
        if (1 < argc) __exit_on_fail = true;
+       
+       std::ifstream __in("testcases.txt");
+       for(;;)
+       {
+               $RETURNTYPE$    __expected;
+               $METHODPARAMDECLARES$
+               __in >> __expected >> $METHODPARAMSTREAMIN$;
+               if (!__in.good()) break;
+               
+               std::cout << "----------------------------------------" << std::endl
+                                 << "Test " << (__pass + __fail) << ": ";
+               std::cout.flush();
+               
+               __timer_start();
+               
+               $CLASSNAME$ object;
+               $RETURNTYPE$ __actual = object.$METHODNAME$($METHODPARAMNAMES$);
+               
+               double __t = __timer_stop();
+               
+               if (__actual == __expected)
+               {
+                       std::cout << "[PASS] in " << __t << " seconds." << std::endl;
+                       ++__pass;
+               }
+               else
+               {
+                       std::cout << "[FAIL] in " << __t << " seconds." << std::endl
+                                         << "->  Input: " << $METHODPARAMSTREAMOUT$ << std::endl
+                                         << "   Actual: " << __actual << std::endl
+                                         << " Expected: " << __expected << std::endl;
+                       ++__fail;
+                       if (__exit_on_fail) exit(1);
+               }
+       }
 
-$TESTCASES$
        std::cout << "========================================" << std::endl
                          << " Total Pass: " << __pass << std::endl
                          << " Total Fail: " << __fail << std::endl;
 
+       if (__fail == 0)
+       {
+               std::cout << std::endl << "Nice!  "
+                                 << "Don't forget to compile remotely before submitting."
+                                 << std::endl;
+       }
+
        return __fail;
 }
 
index 7cd56b2df88a0a78efce28a550e5bcb93442b619..f287af438e7e7e0925d4962d768e38211cc4e028 100644 (file)
@@ -36,7 +36,7 @@ class $CLASSNAME$
 public:
        $RETURNTYPE$ $METHODNAME$($METHODPARAMS$)
        {
-               
+               return $RETURNTYPE$();
        }
 };
 
diff --git a/src/com/dogcows/resources/C++Test b/src/com/dogcows/resources/C++Test
deleted file mode 100644 (file)
index 4316d38..0000000
+++ /dev/null
@@ -1 +0,0 @@
-       __do_test($TESTOUTPUT$, $TESTINPUTS$);
This page took 0.040664 seconds and 4 git commands to generate.