Index: /trunk/FACT++/src/InterpreterV8.cc
===================================================================
--- /trunk/FACT++/src/InterpreterV8.cc	(revision 14606)
+++ /trunk/FACT++/src/InterpreterV8.cc	(revision 14607)
@@ -63,4 +63,15 @@
 // be checked in all placed to avoid that V8 will core dump.
 //
+// HandleScope:
+// ------------
+// A handle scope is a garbage collector and collects all handles created
+// until it goes out of scope. Handles which are not needed anymore are
+// then deleted. To return a handle from a HandleScope you need to use
+// Close(). E.g., String::Utf8Value does not create a new handle and
+// hence does not need a HandleScope. Any ::New will need a handle scope.
+// Forgetting the HandleScope could in principle fill your memory,
+// but everything is properly deleted by the global HandleScope at
+// script termination.
+//
 
 // ==========================================================================
@@ -110,5 +121,4 @@
     // Using a Javascript function has the advantage that it is fully
     // interruptable without the need of C++ code
-
     const string code =
         "(function(){"
@@ -117,11 +127,5 @@
         "})();";
 
-    HandleScope handle_scope;
-
-    const Handle<Script> script = Script::Compile(String::New(code.c_str()), String::New("internal"));
-    if (script.IsEmpty())
-        return Undefined();
-
-    return handle_scope.Close(script->Run());
+    return ExecuteInternal(code);
 }
 
@@ -142,6 +146,6 @@
     TryCatch exception;
 
-    const Handle<Script> sleep = Script::Compile(String::New(("dim.sleep("+to_string(ms)+");").c_str()), String::New("internal"));
-    if (ms==0 || (!sleep.IsEmpty() && !sleep->Run().IsEmpty()))
+    const bool rc = ms==0 || !ExecuteInternal("dim.sleep("+to_string(ms)+");").IsEmpty();
+    if (rc)
     {
         Handle<Value> args[] = {  };
@@ -173,4 +177,6 @@
         return ThrowException(String::New("Argument 0 not an uint32."));
 
+    const HandleScope handle_scope;
+
     Handle<Function> handle = Handle<Function>::Cast(args[1]);
 
@@ -190,6 +196,4 @@
     if (!args[0]->IsString())
         return ThrowException(String::New("Argument 1 must be a string."));
-
-    HandleScope handle_scope;
 
     const String::Utf8Value str(args[0]);
@@ -207,5 +211,5 @@
     }
 
-    return handle_scope.Close(Boolean::New(JsSend(command)));
+    return Boolean::New(JsSend(command));
 }
 
@@ -263,32 +267,5 @@
     code +=        ");";
 
-    HandleScope handle_scope;
-
-    // It is not strictly necessary to catch the exception, instead
-    // script->Run() could just be returned, but catching the
-    // exception allow to print the position in the file in
-    // the exception handler instead of just the posiiton in the script.
-    TryCatch exception;
-
-    const Handle<Script> script = Script::Compile(String::New(code.c_str()), String::New("internal"));
-    if (script.IsEmpty())
-        return Undefined();
-
-    const Handle<Value> result = script->Run();
-
-    return exception.HasCaught() ? exception.ReThrow() : handle_scope.Close(result);
-
-    /*
-    const string   server   = *String::Utf8Value(args[0]);
-    const  int32_t state    = args[1]->Int32Value();
-    const uint32_t millisec = args.Length()==3 ? args[2]->Int32Value() : 0;
-
-    const int rc = JsWait(server, state, millisec);
-
-    if (rc==0 || rc==1)
-        return Boolean::New(rc);
-
-    return ThrowException(String::New(("Waitig for state "+to_string(state)+" of server '"+server+"' failed.").c_str()));
-        */
+    return ExecuteInternal(code);
 }
 
@@ -337,6 +314,4 @@
         return ThrowException(String::New("Argument 3 must be a string."));
 
-    HandleScope handle_scope;
-
     const uint32_t index   = args[0]->Int32Value();
     const string   name    = *String::Utf8Value(args[1]);
@@ -360,5 +335,5 @@
     }
 
-    return handle_scope.Close(Boolean::New(JsNewState(index, name, comment)));
+    return Boolean::New(JsNewState(index, name, comment));
 }
 
@@ -370,6 +345,4 @@
     if (!args[0]->IsUint32() && !args[0]->IsString())
         return ThrowException(String::New("Argument must be an unint32 or a  string."));
-
-    HandleScope handle_scope;
 
     int index = -2;
@@ -389,5 +362,5 @@
         return ThrowException(String::New("State must be in the range [10, 255]."));
 
-    return handle_scope.Close(Boolean::New(JsSetState(index)));
+    return Boolean::New(JsSetState(index));
 }
 
@@ -404,6 +377,4 @@
     for (int i=0; i<args.Length(); i++)
     {
-        const HandleScope handle_scope;
-
         const String::Utf8Value str(args[i]);
         if (*str)
@@ -417,6 +388,4 @@
     for (int i=0; i<args.Length(); i++)
     {
-        const HandleScope handle_scope;
-
         const String::Utf8Value str(args[i]);
         if (*str)
@@ -434,6 +403,4 @@
     for (int i=0; i<args.Length(); i++)
     {
-        const HandleScope handle_scope;
-
         const String::Utf8Value str(args[i]);
         if (*str)
@@ -450,14 +417,12 @@
     for (int i=0; i<args.Length(); i++)
     {
-        const HandleScope handle_scope;
-
         const String::Utf8Value file(args[i]);
         if (*file == NULL)
-            return ThrowException(String::New(("Error loading file '"+string(*file)+"'").c_str()));
+            return ThrowException(String::New("File name missing"));
 
         if (!ExecuteFile(*file))
-            return ThrowException(String::New(("Execution of '"+string(*file)+"' failed").c_str()));
-    }
-    return Undefined();
+            return Boolean::New(false);
+    }
+    return Boolean::New(true);
 }
 
@@ -473,9 +438,7 @@
 Handle<Value> InterpreterV8::FuncDbClose(const Arguments &args)
 {
-    HandleScope handle_scope;
-
     void *ptr = External::Unwrap(args.This()->GetInternalField(0));
     if (!ptr)
-        return handle_scope.Close(Boolean::New(false));
+        return Boolean::New(false);
 
 #ifdef HAVE_SQL
@@ -486,4 +449,6 @@
 #endif
 
+    HandleScope handle_scope;
+
     args.This()->SetInternalField(0, External::New(0));
 
@@ -494,6 +459,4 @@
     if (args.Length()==0)
         return ThrowException(String::New("Arguments expected."));
-
-    HandleScope handle_scope;
 
     void *ptr = External::Unwrap(args.This()->GetInternalField(0));
@@ -509,4 +472,6 @@
     try
     {
+        HandleScope handle_scope;
+
         Database *db = reinterpret_cast<Database*>(ptr);
 
@@ -651,9 +616,9 @@
         return ThrowException(String::New("Argument 1 not a string."));
 
-    HandleScope handle_scope;
-
 #ifdef HAVE_SQL
     try
     {
+        HandleScope handle_scope;
+
         Database *db = new Database(*String::Utf8Value(args[0]));
         fDatabases.push_back(db);
@@ -989,6 +954,4 @@
 Handle<Value> InterpreterV8::OnChangeSet(Local<String> prop, Local< Value > value, const AccessorInfo &)
 {
-    const HandleScope handle_scope;
-
     // Returns the value if the setter intercepts the request. Otherwise, returns an empty handle.
     const string server = *String::Utf8Value(prop);
@@ -1023,8 +986,8 @@
     }
 
-    const HandleScope handle_scope;
-
     if (it->second.IsEmpty() || !it->second->IsFunction())
         return;
+
+    const HandleScope handle_scope;
 
     fGlobalContext->Enter();
@@ -1079,15 +1042,15 @@
     //    return ThrowException(String::New("Must be used as constructor."));
 
-    HandleScope handle_scope;
-
     const String::Utf8Value str(args[0]);
 
     const auto it = fReverseMap.find(*str);
     if (it!=fReverseMap.end())
-        return handle_scope.Close(it->second);
+        return it->second;
 
     void *ptr = JsSubscribe(*str);
     if (ptr==0)
         return ThrowException(String::New(("Subscription to '"+string(*str)+"' already exists.").c_str()));
+
+    HandleScope handle_scope;
 
     Handle<ObjectTemplate> tem = ObjectTemplate::New();
@@ -1153,6 +1116,6 @@
     Handle<ObjectTemplate> loc = ObjectTemplate::New();
 
-    loc->Set(String::New("zd"), Number::New(zd), ReadOnly);
-    loc->Set(String::New("az"), Number::New(az), ReadOnly);
+    loc->Set(String::New("zd"),       Number::New(zd), ReadOnly);
+    loc->Set(String::New("az"),       Number::New(az), ReadOnly);
     loc->Set(String::New("toSky"),    FunctionTemplate::New(LocalToSky), ReadOnly);
     loc->Set(String::New("toString"), FunctionTemplate::New(LocalToString), ReadOnly);
@@ -1167,6 +1130,6 @@
     Handle<ObjectTemplate> sky = ObjectTemplate::New();
 
-    sky->Set(String::New("ra"),  Number::New(ra),  ReadOnly);
-    sky->Set(String::New("dec"), Number::New(dec), ReadOnly);
+    sky->Set(String::New("ra"),       Number::New(ra),  ReadOnly);
+    sky->Set(String::New("dec"),      Number::New(dec), ReadOnly);
     sky->Set(String::New("toLocal"),  FunctionTemplate::New(ismoon?MoonToLocal :SkyToLocal),  ReadOnly);
     sky->Set(String::New("toString"), FunctionTemplate::New(ismoon?MoonToString:SkyToString), ReadOnly);
@@ -1179,6 +1142,4 @@
 Handle<Value> InterpreterV8::LocalDist(const Arguments &args)
 {
-    HandleScope handle_scope;
-
     if (args.Length()!=2)
         return ThrowException(String::New("dist must not be called with two arguments."));
@@ -1186,4 +1147,6 @@
     if (!args[0]->IsObject() || !args[1]->IsObject())
         return ThrowException(String::New("at least one argument not an object."));
+
+    HandleScope handle_scope;
 
     Handle<Object> obj[2] =
@@ -1228,6 +1191,4 @@
 Handle<Value> InterpreterV8::MoonDisk(const Arguments &args)
 {
-    HandleScope handle_scope;
-
     if (args.Length()>1)
         return ThrowException(String::New("disk must not be called with more than one argument."));
@@ -1236,11 +1197,9 @@
     const Time utc = args.Length()==0 ? Time() : Time(v/1000, v%1000);
 
-    return handle_scope.Close(Number::New(ln_get_lunar_disk(utc.JD())));
+    return Number::New(ln_get_lunar_disk(utc.JD()));
 }
 
 Handle<Value> InterpreterV8::LocalToSky(const Arguments &args)
 {
-    HandleScope handle_scope;
-
     if (args.Length()>1)
         return ThrowException(String::New("toSky must not be called with more than one argument."));
@@ -1252,4 +1211,6 @@
     if (!finite(hrz.alt) || !finite(hrz.az))
         return ThrowException(String::New("zd and az must be finite."));
+
+    HandleScope handle_scope;
 
     const Local<Value> date =
@@ -1273,6 +1234,4 @@
 Handle<Value> InterpreterV8::SkyToLocal(const Arguments &args)
 {
-    HandleScope handle_scope;
-
     if (args.Length()>1)
         return ThrowException(String::New("toLocal must not be called with more than one argument."));
@@ -1284,4 +1243,6 @@
     if (!finite(equ.ra) || !finite(equ.dec))
         return ThrowException(String::New("Ra and dec must be finite."));
+
+    HandleScope handle_scope;
 
     const Local<Value> date =
@@ -1305,6 +1266,4 @@
 Handle<Value> InterpreterV8::MoonToLocal(const Arguments &args)
 {
-    HandleScope handle_scope;
-
     if (args.Length()>0)
         return ThrowException(String::New("toLocal must not be called with arguments."));
@@ -1316,4 +1275,6 @@
     if (!finite(equ.ra) || !finite(equ.dec))
         return ThrowException(String::New("ra and dec must be finite."));
+
+    HandleScope handle_scope;
 
     const Local<Value> date =
@@ -1337,8 +1298,8 @@
 Handle<Value> InterpreterV8::ConstructorMoon(const Arguments &args)
 {
-    HandleScope handle_scope;
-
     if (args.Length()>1)
         return ThrowException(String::New("Moon constructor must not be called with more than one argument."));
+
+    HandleScope handle_scope;
 
     const Local<Value> date =
@@ -1358,6 +1319,4 @@
 Handle<Value> InterpreterV8::ConstructorSky(const Arguments &args)
 {
-    HandleScope handle_scope;
-
     if (args.Length()!=2)
         return ThrowException(String::New("Sky constructor takes two arguments."));
@@ -1369,11 +1328,9 @@
         return ThrowException(String::New("Both arguments to Sky must be valid numbers."));
 
-    return handle_scope.Close(ConstructSky(ra, dec));
+    return ConstructSky(ra, dec);
 }
 
 Handle<Value> InterpreterV8::ConstructorLocal(const Arguments &args)
 {
-    HandleScope handle_scope;
-
     if (args.Length()!=2)
         return ThrowException(String::New("Local constructor takes two arguments."));
@@ -1385,5 +1342,5 @@
         return ThrowException(String::New("Both arguments to Local must be valid numbers."));
 
-    return handle_scope.Close(ConstructLocal(zd, az));
+    return ConstructLocal(zd, az);
 }
 #endif
@@ -1425,4 +1382,5 @@
     }
 
+    // -------------- SKIP if 'internal' and 'Error' ---------------
     if (*exception)
         out << *exception;
@@ -1434,4 +1392,5 @@
     if (*sourceline)
         JsException(*sourceline);
+    // -------------- SKIP if 'internal' and 'Error: ' ---------------
 
     // Print wavy underline (GetUnderline is deprecated).
@@ -1458,4 +1417,6 @@
     const boost::tokenizer<separator> tokenizer(trace, separator("\n"));
 
+    // maybe skip: "    at internal:"
+
     auto it = tokenizer.begin();
     JsException("");
@@ -1466,21 +1427,30 @@
 }
 
-// Executes a string within the current v8 context.
-bool InterpreterV8::ExecuteStringNT(const Handle<String> &code, const Handle<Value> &file)
-{
-    if (code.IsEmpty())
-        return true;
-
-    const HandleScope handle_scope;
-
-    const Handle<Script> script = Script::Compile(code, file);
+Handle<Value> InterpreterV8::ExecuteInternal(const string &code)
+{
+    TryCatch exception;
+    const Handle<Value> result = ExecuteCode(code);
+    return exception.HasCaught() ? exception.ReThrow() : result;
+}
+
+Handle<Value> InterpreterV8::ExecuteCode(const string &code, const string &file, bool main)
+{
+    HandleScope handle_scope;
+
+    const Handle<String> source = String::New(code.c_str(), code.size());
+    const Handle<String> origin = String::New(file.c_str());
+    if (source.IsEmpty())
+        return Handle<Value>();
+
+    const Handle<Script> script = Script::Compile(source, origin);
     if (script.IsEmpty())
-        return false;
-
-    JsSetState(3);
+        return Handle<Value>();
+
+    if (main)
+        JsSetState(3);
 
     const Handle<Value> result = script->Run();
     if (result.IsEmpty())
-        return false;
+        return result;
 
     // If all went well and the result wasn't undefined then print
@@ -1489,30 +1459,8 @@
         JsResult(*String::Utf8Value(result));
 
-    return true;
-}
-
-bool InterpreterV8::ExecuteCode(const Handle<String> &code, const Handle<Value> &file)
-{
-    TryCatch exception;
-
-    const bool rc = ExecuteStringNT(code, file);
-
-    // Check if this is a termination exception
-    //if (!exception.CanContinue())
-    //    return false;
-
-    if (exception.HasCaught())
-        return ReportException(&exception);
-
-    return rc;
-}
-
-bool InterpreterV8::ExecuteCode(const string &code, const string &file)
-{
-    return ExecuteCode(String::New(code.c_str(), code.size()),
-                       String::New(file.c_str()));
-}
-
-bool InterpreterV8::ExecuteFile(const string &name)
+    return handle_scope.Close(result);
+}
+
+bool InterpreterV8::ExecuteFile(const string &name, bool main)
 {
     ifstream fin(name.c_str());
@@ -1533,5 +1481,5 @@
     }
 
-    return ExecuteCode(buffer, name);
+    return !ExecuteCode(buffer, name, main).IsEmpty();
 }
 
@@ -1567,6 +1515,6 @@
                 "case 'x': val = parseInt(arr[i]).toString(base?base:16); break;"
                 "case 'd': val = parseFloat(parseInt(arr[i], base?base:10).toPrecision(exp)).toFixed(0); break;"
-                "default:\n"
-                "    throw new SyntaxError('Conversion specifier '+p4+' unknown.');\n"
+                //"default:\n"
+                //"    throw new SyntaxError('Conversion specifier '+p4+' unknown.');\n"
                 "}"
                 ""
@@ -1581,17 +1529,17 @@
             "}"
             ""
-            "var regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?(.)/g;"
+            "var regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd])/g;"
             "return str.replace(regex, callback);"
         "}"
         "\n"
-        "String.prototype.format = function()"
+        "String.prototype.$ = function()"
         "{"
             "return dim.format(this, Array.prototype.slice.call(arguments));"
-        "}"
+        "}"/*
         "\n"
         "var format = function()"
         "{"
             "return dim.format(arguments[0], Array.prototype.slice.call(arguments,1));"
-        "}";
+        "}"*/;
 
     Script::New(String::New(code.c_str()), String::New("internal"))->Run();
@@ -1607,5 +1555,5 @@
     JsLoad(filename);
 
-    HandleScope handle_scope;
+    const HandleScope handle_scope;
 
     // Create a template for the global object.
@@ -1668,7 +1616,15 @@
 
     //context->Enter();
+
+    TryCatch exception;
+
     Locker::StartPreemption(10);
-    const bool rc = ExecuteFile(filename);
+    bool rc = ExecuteFile(filename, true);
+    Locker::StopPreemption();
+
     Terminate();
+
+    if (exception.HasCaught())
+        rc = ReportException(&exception);
 
     // -----
@@ -1684,5 +1640,4 @@
     // }
 
-    Locker::StopPreemption();
     //context->Exit();
 
Index: /trunk/FACT++/src/InterpreterV8.h
===================================================================
--- /trunk/FACT++/src/InterpreterV8.h	(revision 14606)
+++ /trunk/FACT++/src/InterpreterV8.h	(revision 14607)
@@ -49,8 +49,7 @@
 
     bool ReportException(v8::TryCatch* try_catch);
-    bool ExecuteStringNT(const v8::Handle<v8::String> &code, const v8::Handle<v8::Value>  &file);
-    bool ExecuteCode(const v8::Handle<v8::String> &code, const v8::Handle<v8::Value>  &file);
-    bool ExecuteCode(const std::string &code, const std::string &file="");
-    bool ExecuteFile(const std::string &name);
+    bool ExecuteFile(const std::string &name, bool main=false);
+    v8::Handle<v8::Value> ExecuteCode(const std::string &code, const std::string &file="internal", bool main=false);
+    v8::Handle<v8::Value> ExecuteInternal(const std::string &code);
 
     void ThreadTimeout(v8::Persistent<v8::Function> func, uint32_t ms);
