]> git.saurik.com Git - cycript.git/blobdiff - Console.cpp
Limit recompilation of files upon changed grammar.
[cycript.git] / Console.cpp
index f6ba47bfc16bdf1b62ce99518b71a5b465129676..57f437555c13467b3bae0e7cb222834e4cb7951e 100644 (file)
 
 #include <dlfcn.h>
 
+#ifdef __APPLE__
+#include <mach/mach_time.h>
+#endif
+
 #include "Display.hpp"
 #include "Driver.hpp"
 #include "Highlight.hpp"
-#include "Replace.hpp"
+#include "Parser.hpp"
 
 static volatile enum {
     Working,
@@ -94,6 +98,7 @@ static void sigint(int) {
 }
 
 static bool bison_;
+static bool timing_;
 static bool strict_;
 static bool pretty_;
 
@@ -420,13 +425,13 @@ static void Console(CYOptions &options) {
                 goto read;
             }
 
-            if (driver.program_ == NULL)
+            if (driver.script_ == NULL)
                 goto restart;
 
             std::stringbuf str;
             CYOutput out(str, options);
             Setup(out, driver, options, lower);
-            out << *driver.program_;
+            out << *driver.script_;
             code = str.str();
         }
 
@@ -444,6 +449,16 @@ static void Console(CYOptions &options) {
 
 void InjectLibrary(pid_t, int, const char *const []);
 
+static uint64_t CYGetTime() {
+#ifdef __APPLE__
+    return mach_absolute_time();
+#else
+    struct timespec spec;
+    clock_gettime(CLOCK_MONOTONIC, &spec);
+    return spec.tv_sec * UINT64_C(1000000000) + spec.tv_nsec;
+#endif
+}
+
 int Main(int argc, char * const argv[], char const * const envp[]) {
     bool tty(isatty(STDIN_FILENO));
     bool compile(false);
@@ -521,6 +536,8 @@ int Main(int argc, char * const argv[], char const * const envp[]) {
                     options.verbose_ = true;
                 else if (strcmp(optarg, "bison") == 0)
                     bison_ = true;
+                else if (strcmp(optarg, "timing") == 0)
+                    timing_ = true;
                 else {
                     fprintf(stderr, "invalid name for -g\n");
                     return 1;
@@ -744,6 +761,44 @@ int Main(int argc, char * const argv[], char const * const envp[]) {
             _assert(!stream->fail());
         }
 
+        if (timing_) {
+            std::stringbuf buffer;
+            stream->get(buffer, '\0');
+            _assert(!stream->fail());
+
+            double average(0);
+            int samples(-50);
+            uint64_t start(CYGetTime());
+
+            for (;;) {
+                stream = new std::istringstream(buffer.str());
+
+                CYPool pool;
+                CYDriver driver(pool, *stream, script);
+                Setup(driver);
+
+                uint64_t begin(CYGetTime());
+                driver.Parse();
+                uint64_t end(CYGetTime());
+
+                delete stream;
+
+                average += (end - begin - average) / ++samples;
+
+                uint64_t now(CYGetTime());
+                if (samples == 0)
+                    average = 0;
+                else if ((now - start) / 1000000000 >= 1)
+                    std::cout << std::fixed << average << '\t' << (end - begin) << '\t' << samples << std::endl;
+                else continue;
+
+                start = now;
+            }
+
+            stream = new std::istringstream(buffer.str());
+            std::cin.get();
+        }
+
         CYPool pool;
         CYDriver driver(pool, *stream, script);
         Setup(driver);
@@ -753,11 +808,11 @@ int Main(int argc, char * const argv[], char const * const envp[]) {
         if (failed || !driver.errors_.empty()) {
             for (CYDriver::Errors::const_iterator i(driver.errors_.begin()); i != driver.errors_.end(); ++i)
                 std::cerr << i->location_.begin << ": " << i->message_ << std::endl;
-        } else if (driver.program_ != NULL) {
+        } else if (driver.script_ != NULL) {
             std::stringbuf str;
             CYOutput out(str, options);
             Setup(out, driver, options, true);
-            out << *driver.program_;
+            out << *driver.script_;
             std::string code(str.str());
             if (compile)
                 std::cout << code;