11 #include <boost/tokenizer.hpp> 12 #include <boost/algorithm/string/join.hpp> 97 Handle<Value> InterpreterV8::FuncExit(
const Arguments &)
99 V8::TerminateExecution(fThreadId);
104 return ThrowException(Null());
107 Handle<Value> InterpreterV8::FuncSleep(
const Arguments& args)
109 if (args.Length()==0)
119 if (args.Length()!=1)
120 return ThrowException(String::New(
"Number of arguments must be exactly 1."));
122 if (!args[0]->IsUint32())
123 return ThrowException(String::New(
"Argument 1 must be an uint32."));
130 "while ((new Date()-t)<"+to_string(args[0]->Int32Value())+
") v8.sleep();" 133 return ExecuteInternal(code);
136 Handle<Value> InterpreterV8::FuncTimeout(
const Arguments &args)
139 return ThrowException(String::New(
"Number of arguments must be at least two."));
141 if (!args[0]->IsNull() && !args[0]->IsInt32())
142 return ThrowException(String::New(
"Argument 0 not null and not an int32."));
144 if (!args[1]->IsFunction())
145 return ThrowException(String::New(
"Argument 1 not a function."));
147 if (args.Length()>2 && !args[2]->IsObject())
148 return ThrowException(String::New(
"Argument 2 not an object."));
150 const int32_t timeout = args[0]->IsNull() ? 0 : args[0]->Int32Value();
151 const bool null = args[0]->IsNull();
153 HandleScope handle_scope;
155 Handle<Function> func = Handle<Function>::Cast(args[1]);
157 const int nn = args.Length()==2 ? 0 : args.Length()-3;
159 Handle<Value> argv[nn];
160 for (
int i=0;
i<nn;
i++)
166 const Handle<Value> rc = args.Length()<3 ? func->Call(func, nn, argv) : func->Call(args[2]->ToObject(), nn, argv);
170 if (!rc->IsUndefined())
171 return handle_scope.Close(rc);
173 if (!null &&
Time()-t>=boost::posix_time::milliseconds(abs(timeout)))
186 const string str =
"Waiting for func to return a defined value timed out.";
187 return ThrowException(String::New(str.c_str()));
190 void InterpreterV8::Thread(
int &
id, Persistent<Object> _this, Persistent<Function> func, uint32_t ms)
205 const int id_local = V8::GetCurrentThreadId();
207 fThreadIds.insert(id_local);
209 const HandleScope handle_scope;
211 func->CreationContext()->Enter();
215 const bool rc = ms==0 || !ExecuteInternal(
"v8.sleep("+to_string(ms)+
");").IsEmpty();
219 func->Call(func, 0, NULL);
221 func->Call(_this, 0, NULL);
227 fThreadIds.erase(id_local);
229 if (!HandleException(exception,
"thread"))
230 V8::TerminateExecution(fThreadId);
232 func->CreationContext()->Exit();
235 Handle<Value> InterpreterV8::FuncThread(
const Arguments& args)
237 if (!args.IsConstructCall())
238 return ThrowException(String::New(
"Thread must be called as constructor."));
240 if (args.Length()!=2 && args.Length()!=3)
241 return ThrowException(String::New(
"Number of arguments must be two or three."));
243 if (!args[0]->IsUint32())
244 return ThrowException(String::New(
"Argument 0 not an uint32."));
246 if (!args[1]->IsFunction())
247 return ThrowException(String::New(
"Argument 1 not a function."));
249 if (args.Length()==3 && !args[2]->IsObject())
250 return ThrowException(String::New(
"Argument 2 not an object."));
255 const HandleScope handle_scope;
257 Handle<Function> handle = Handle<Function>::Cast(args[1]);
259 Persistent<Function> func = Persistent<Function>::New(handle);
260 Persistent<Object> _this;
261 if (args.Length()==3)
262 _this = Persistent<Object>::New(args[2]->ToObject());
264 const uint32_t ms = args[0]->Uint32Value();
275 Handle<Object>
self = args.This();
277 self->Set(String::New(
"id"), Integer::NewFromUnsigned(
id), ReadOnly);
278 self->Set(String::New(
"kill"), FunctionTemplate::New(WrapKill)->GetFunction(), ReadOnly);
283 Handle<Value> InterpreterV8::FuncKill(
const Arguments& args)
285 const uint32_t
id = args.This()->Get(String::New(
"id"))->Uint32Value();
287 V8::TerminateExecution(
id);
289 return Boolean::New(fThreadIds.erase(
id));
292 Handle<Value> InterpreterV8::FuncSend(
const Arguments& args)
294 if (args.Length()==0)
295 return ThrowException(String::New(
"Number of arguments must be at least 1."));
297 if (!args[0]->IsString())
298 return ThrowException(String::New(
"Argument 1 must be a string."));
300 const String::AsciiValue
str(args[0]);
302 string command = *
str;
304 if (command.length()==0)
305 return ThrowException(String::New(
"Server name empty."));
307 if (args.Length()==0)
309 if (command.find_first_of(
'/')==string::npos)
314 for (
int i=1;
i<args.Length();
i++)
316 string arg = *String::AsciiValue(args[
i]);
319 if (args[
i]->IsString())
321 boost::replace_all(arg,
"\\",
"\\\\");
322 boost::replace_all(arg,
"'",
"\\'");
323 boost::replace_all(arg,
"\"",
"\\\"");
331 return Boolean::New(JsSend(command));
333 catch (
const runtime_error &e)
335 return ThrowException(String::New(e.what()));
343 Handle<Value> InterpreterV8::FuncWait(
const Arguments& args)
345 if (args.Length()!=2 && args.Length()!=3)
346 return ThrowException(String::New(
"Number of arguments must be 2 or 3."));
348 if (!args[0]->IsString())
349 return ThrowException(String::New(
"Argument 1 not a string."));
351 if (!args[1]->IsInt32() && !args[1]->IsString())
352 return ThrowException(String::New(
"Argument 2 not an int32 and not a string."));
354 if (args.Length()==3 && !args[2]->IsInt32() && !args[2]->IsUndefined())
355 return ThrowException(String::New(
"Argument 3 not an int32 and not undefined."));
360 const string index = args[1]->IsInt32() ?
"s.index" :
"s.name";
361 const bool timeout = args.Length()==3 && !args[2]->IsUndefined();
362 const string arg0 = *String::AsciiValue(args[0]);
363 const string state = args[1]->IsString() ? *String::AsciiValue(args[1]) :
"";
364 const string arg1 = args[1]->IsString() ? (
"\""+state+
"\"") : to_string(args[1]->Int32Value());
365 const bool isNot = arg0[0]==
'!';
366 const string name = isNot ? arg0.substr(1) : arg0;
368 if (arg0.find_first_of(
"\"'")!=string::npos)
369 return ThrowException(String::New(
"Server name must not contain quotation marks."));
371 if (args[1]->IsString())
372 if (state.find_first_of(
"\"'")!=string::npos)
373 return ThrowException(String::New(
"State name must not contain quotation marks."));
375 string code =
"(function(name,state,ms)" 378 code +=
"var t = new Date();";
381 "var s = dim.state(name);" 382 "if(!s)throw new Error('Waiting for state "+arg1+
" of server "+arg0+
" failed.');";
385 "if(state!="+index+
")return true;";
388 "if(state=="+index+
")return true;";
390 code +=
"if((new Date()-t)>Math.abs(ms))break;";
392 code +=
"v8.sleep();" 395 code +=
"if(ms>0)throw new Error('Waiting for state "+arg1+
" of server "+arg0+
" timed out.');";
396 code +=
"return false;" 397 "})('"+name+
"',"+arg1;
399 code +=
"," + (args[2]->IsUndefined()?
"undefined":to_string(args[2]->Int32Value()));
402 return ExecuteInternal(code);
405 Handle<Value> InterpreterV8::FuncState(
const Arguments& args)
407 if (args.Length()!=1)
408 return ThrowException(String::New(
"Number of arguments must be exactly 1."));
410 if (!args[0]->IsString())
411 return ThrowException(String::New(
"Argument 1 must be a string."));
415 const String::AsciiValue
str(args[0]);
417 const State rc = JsState(*str);
421 HandleScope handle_scope;
423 Handle<Object> obj = Object::New();
425 obj->Set(String::New(
"server"), String::New(*str), ReadOnly);
426 obj->Set(String::New(
"index"), Integer::New(rc.
index), ReadOnly);
427 obj->Set(String::New(
"name"), String::New(rc.
name.c_str()), ReadOnly);
430 if (rc.
index>-256 && !date.IsEmpty())
431 obj->Set(String::New(
"time"), date);
433 return handle_scope.Close(obj);
436 Handle<Value> InterpreterV8::FuncNewState(
const Arguments& args)
438 if (args.Length()<1 || args.Length()>3)
439 return ThrowException(String::New(
"Number of arguments must be 1, 2 or 3."));
441 if (!args[0]->IsUint32())
442 return ThrowException(String::New(
"Argument 1 must be an uint32."));
443 if (args.Length()>1 && !args[1]->IsString())
444 return ThrowException(String::New(
"Argument 2 must be a string."));
445 if (args.Length()>2 && !args[2]->IsString())
446 return ThrowException(String::New(
"Argument 3 must be a string."));
448 const uint32_t index = args[0]->Int32Value();
449 const string name = *String::AsciiValue(args[1]);
450 const string comment = *String::AsciiValue(args[2]);
452 if (index<10 || index>255)
453 return ThrowException(String::New(
"State must be in the range [10, 255]."));
456 return ThrowException(String::New(
"State name must not be empty."));
458 if (name.find_first_of(
':')!=string::npos || name.find_first_of(
'=')!=string::npos)
459 return ThrowException(String::New(
"State name must not contain : or =."));
463 Find(
int idx,
const string &n) :
State(idx, n) { }
464 bool operator()(
const pair<int, string> &p) {
return index==p.first || name==p.second; }
467 if (find_if(fStates.begin(), fStates.end(), Find(index, name))!=fStates.end())
470 "State index ["+to_string(index)+
"] or name ["+name+
"] already defined.";
472 return ThrowException(String::New(what.c_str()));
475 return Boolean::New(JsNewState(index, name, comment));
478 Handle<Value> InterpreterV8::FuncSetState(
const Arguments& args)
480 if (args.Length()!=1)
481 return ThrowException(String::New(
"Number of arguments must be exactly 1."));
483 if (!args[0]->IsUint32() && !args[0]->IsString())
484 return ThrowException(String::New(
"Argument must be an unint32 or a string."));
487 if (args[0]->IsUint32())
489 index = args[0]->Int32Value();
493 const string name = *String::AsciiValue(args[0]);
494 index = JsGetState(name);
496 return ThrowException(String::New((
"State '"+name+
"' not found.").c_str()));
499 if (index<10 || index>255)
500 return ThrowException(String::New(
"State must be in the range [10, 255]."));
502 return Boolean::New(JsSetState(index));
505 Handle<Value> InterpreterV8::FuncGetState(
const Arguments& args)
508 return ThrowException(String::New(
"getState must not take arguments."));
510 const State state = JsGetCurrentState();
512 HandleScope handle_scope;
514 Handle<Object> rc = Object::New();
518 rc->Set(String::New(
"index"), Integer::New(state.
index), ReadOnly);
519 rc->Set(String::New(
"name"), String::New(state.
name.c_str()), ReadOnly);
520 rc->Set(String::New(
"description"), String::New(state.
comment.c_str()), ReadOnly);
522 return handle_scope.Close(rc);
525 Handle<Value> InterpreterV8::FuncGetStates(
const Arguments& args)
528 return ThrowException(String::New(
"getStates must not take more than one arguments."));
530 if (args.Length()==1 && !args[0]->IsString())
531 return ThrowException(String::New(
"Argument must be a string."));
533 const string server = args.Length()==1 ? *String::AsciiValue(args[0]) :
"DIM_CONTROL";
535 const vector<State>
states = JsGetStates(server);
537 HandleScope handle_scope;
539 Handle<Object> list = Object::New();
543 for (
auto it=states.begin(); it!=states.end(); it++)
545 Handle<Value> entry = StringObject::New(String::New(it->name.c_str()));
549 StringObject::Cast(*entry)->Set(String::New(
"description"), String::New(it->comment.c_str()), ReadOnly);
550 list->Set(Integer::New(it->index), entry, ReadOnly);
553 return handle_scope.Close(list);
556 Handle<Value> InterpreterV8::FuncGetDescription(
const Arguments& args)
558 if (args.Length()!=1)
559 return ThrowException(String::New(
"getDescription must take exactly one argument."));
561 if (args.Length()==1 && !args[0]->IsString())
562 return ThrowException(String::New(
"Argument must be a string."));
564 const string service = *String::AsciiValue(args[0]);
566 const vector<Description> descriptions = JsGetDescription(service);
567 const set<Service> services = JsGetServices();
569 auto is=services.begin();
570 for (; is!=services.end(); is++)
571 if (is->name==service)
574 if (is==services.end())
577 HandleScope handle_scope;
579 Handle<Object> arr = fTemplateDescription->GetFunction()->NewInstance();
583 auto it=descriptions.begin();
584 arr->Set(String::New(
"name"), String::New(it->name.c_str()), ReadOnly);
585 if (!it->comment.empty())
586 arr->Set(String::New(
"description"), String::New(it->comment.c_str()), ReadOnly);
587 if (is!=services.end())
589 arr->Set(String::New(
"server"), String::New(is->server.c_str()), ReadOnly);
590 arr->Set(String::New(
"service"), String::New(is->service.c_str()), ReadOnly);
591 arr->Set(String::New(
"isCommand"), Boolean::New(is->iscmd), ReadOnly);
592 if (!is->format.empty())
593 arr->Set(String::New(
"format"), String::New(is->format.c_str()), ReadOnly);
597 for (it++; it!=descriptions.end(); it++)
599 Handle<Object> obj = Object::New();
603 if (!it->name.empty())
604 obj->Set(String::New(
"name"), String::New(it->name.c_str()), ReadOnly);
605 if (!it->comment.empty())
606 obj->Set(String::New(
"description"), String::New(it->comment.c_str()), ReadOnly);
607 if (!it->unit.empty())
608 obj->Set(String::New(
"unit"), String::New(it->unit.c_str()), ReadOnly);
613 return handle_scope.Close(arr);
616 Handle<Value> InterpreterV8::FuncGetServices(
const Arguments& args)
619 return ThrowException(String::New(
"getServices must not take more than two argument."));
621 if (args.Length()>=1 && !args[0]->IsString())
622 return ThrowException(String::New(
"First argument must be a string."));
624 if (args.Length()==2 && !args[1]->IsBoolean())
625 return ThrowException(String::New(
"Second argument must be a boolean."));
627 string arg0 = args.Length() ? *String::AsciiValue(args[0]) :
"";
631 const set<Service> services = JsGetServices();
633 HandleScope handle_scope;
635 Handle<Array> arr = Array::New();
640 for (
auto is=services.begin(); is!=services.end(); is++)
642 if (!arg0.empty() && is->name.find(arg0)!=0)
645 if (args.Length()==2 && args[1]->BooleanValue()!=is->iscmd)
648 Handle<Object> obj = Object::New();
652 obj->Set(String::New(
"name"), String::New(is->name.c_str()), ReadOnly);
653 obj->Set(String::New(
"server"), String::New(is->server.c_str()), ReadOnly);
654 obj->Set(String::New(
"service"), String::New(is->service.c_str()), ReadOnly);
655 obj->Set(String::New(
"isCommand"), Boolean::New(is->iscmd), ReadOnly);
656 if (!is->format.empty())
657 obj->Set(String::New(
"format"), String::New(is->format.c_str()), ReadOnly);
662 return handle_scope.Close(arr);
673 Handle<Value> InterpreterV8::FuncLog(
const Arguments& args)
675 for (
int i=0; i<args.Length(); i++)
677 const String::AsciiValue
str(args[i]);
682 if (args.Length()==0)
688 Handle<Value> InterpreterV8::FuncAlarm(
const Arguments& args)
690 for (
int i=0; i<args.Length(); i++)
692 const String::AsciiValue
str(args[i]);
697 if (args.Length()==0)
703 Handle<Value> InterpreterV8::FuncOut(
const Arguments& args)
705 for (
int i=0; i<args.Length(); i++)
707 const String::AsciiValue
str(args[i]);
714 Handle<Value> InterpreterV8::FuncWarn(
const Arguments& args)
716 for (
int i=0; i<args.Length(); i++)
718 const String::AsciiValue
str(args[i]);
728 Handle<Value> InterpreterV8::FuncInclude(
const Arguments& args)
730 if (args.Length()!=1)
731 return ThrowException(String::New(
"Number of arguments must be one."));
733 if (!args[0]->IsString())
734 return ThrowException(String::New(
"Argument must be a string."));
736 const String::AsciiValue file(args[0]);
738 return ThrowException(String::New(
"File name missing."));
740 if (strlen(*file)==0)
741 return ThrowException(String::New(
"File name empty."));
745 return ThrowException(String::New(errno!=0?strerror(errno):
"Insufficient memory for decompression"));
748 getline(fin, buffer,
'\0');
750 if ((fin.fail() && !fin.eof()) || fin.bad())
751 return ThrowException(String::New(strerror(errno)));
753 if (buffer.length()>1 && buffer[0]==
'#' && buffer[1]==
'!')
754 buffer.insert(0,
"//");
756 return ExecuteCode(buffer, *file);
759 Handle<Value> InterpreterV8::FuncFile(
const Arguments& args)
761 if (args.Length()!=1 && args.Length()!=2)
762 return ThrowException(String::New(
"Number of arguments must be one or two."));
764 const String::AsciiValue file(args[0]);
766 return ThrowException(String::New(
"File name missing"));
768 if (args.Length()==2 && !args[1]->IsString())
769 return ThrowException(String::New(
"Second argument must be a string."));
771 const string delim = args.Length()==2 ? *String::AsciiValue(args[1]) :
"";
773 if (args.Length()==2 && delim.size()!=1)
774 return ThrowException(String::New(
"Second argument must be a string of length 1."));
776 HandleScope handle_scope;
780 return ThrowException(String::New(errno!=0?strerror(errno):
"Insufficient memory for decompression"));
782 if (args.Length()==1)
785 getline(fin, buffer,
'\0');
786 if ((fin.fail() && !fin.eof()) || fin.bad())
787 return ThrowException(String::New(strerror(errno)));
789 Handle<Value> str = StringObject::New(String::New(buffer.c_str()));
790 StringObject::Cast(*str)->Set(String::New(
"name"), String::New(*file));
791 return handle_scope.Close(str);
794 Handle<Array> arr = Array::New();
800 while (getline(fin, buffer, delim[0]))
801 arr->Set(i++, String::New(buffer.c_str()));
803 if ((fin.fail() && !fin.eof()) || fin.bad())
804 return ThrowException(String::New(strerror(errno)));
806 arr->Set(String::New(
"name"), String::New(*file));
807 arr->Set(String::New(
"delim"), String::New(delim.c_str(), 1));
809 return handle_scope.Close(arr);
816 Handle<Value> InterpreterV8::ConstructorMail(
const Arguments &args)
818 if (!args.IsConstructCall())
819 return ThrowException(String::New(
"Mail must be called as constructor"));
821 if (args.Length()!=1 || !args[0]->IsString())
822 return ThrowException(String::New(
"Constructor must be called with a single string as argument"));
824 HandleScope handle_scope;
826 Handle<Array> rec = Array::New();
827 Handle<Array> att = Array::New();
828 Handle<Array> bcc = Array::New();
829 Handle<Array> cc = Array::New();
830 Handle<Array> txt = Array::New();
831 if (rec.IsEmpty() || att.IsEmpty() || bcc.IsEmpty() || cc.IsEmpty() || txt.IsEmpty())
834 Handle<Object>
self = args.This();
836 self->Set(String::New(
"subject"), args[0]->ToString(), ReadOnly);
837 self->Set(String::New(
"recipients"), rec, ReadOnly);
838 self->Set(String::New(
"attachments"), att, ReadOnly);
839 self->Set(String::New(
"bcc"), bcc, ReadOnly);
840 self->Set(String::New(
"cc"), cc, ReadOnly);
841 self->Set(String::New(
"text"), txt, ReadOnly);
843 self->Set(String::New(
"send"), FunctionTemplate::New(WrapSendMail)->GetFunction(), ReadOnly);
845 return handle_scope.Close(
self);
848 vector<string> InterpreterV8::ValueToArray(
const Handle<Value> &val,
bool only)
852 Handle<Array> arr = Handle<Array>::Cast(val);
853 for (uint32_t i=0; i<arr->Length(); i++)
855 Handle<Value> obj = arr->Get(i);
859 if (obj->IsNull() || obj->IsUndefined())
862 if (only && !obj->IsString())
865 rc.push_back(*String::AsciiValue(obj->ToString()));
871 Handle<Value> InterpreterV8::FuncSendMail(
const Arguments& args)
873 HandleScope handle_scope;
876 return ThrowException(String::New(
"Only one argument allowed."));
878 if (args.Length()==1 && !args[0]->IsBoolean())
879 return ThrowException(String::New(
"Argument must be a boolean."));
881 const bool block = args.Length()==0 || args[0]->BooleanValue();
883 const Handle<Value> sub = args.This()->Get(String::New(
"subject"));
884 const Handle<Value> rec = args.This()->Get(String::New(
"recipients"));
885 const Handle<Value> txt = args.This()->Get(String::New(
"text"));
886 const Handle<Value> att = args.This()->Get(String::New(
"attachments"));
887 const Handle<Value> bcc = args.This()->Get(String::New(
"bcc"));
888 const Handle<Value> cc = args.This()->Get(String::New(
"cc"));
890 const vector<string> vrec = ValueToArray(rec);
891 const vector<string> vtxt = ValueToArray(txt,
false);
892 const vector<string> vatt = ValueToArray(att);
893 const vector<string> vbcc = ValueToArray(bcc);
894 const vector<string> vcc = ValueToArray(cc);
897 return ThrowException(String::New(
"At least one valid string is required in 'recipients'."));
899 return ThrowException(String::New(
"At least one valid string is required in 'text'."));
901 const string subject = *String::AsciiValue(sub->ToString());
903 FILE *pipe = popen((
"from=no-reply@fact-project.org mailx -~ "+vrec[0]).c_str(),
"w");
905 return ThrowException(String::New(strerror(errno)));
907 fprintf(pipe,
"%s", (
"~s"+subject+
"\n").c_str());
908 for (
auto it=vrec.begin()+1; it<vrec.end(); it++)
909 fprintf(pipe,
"%s", (
"~t"+*it+
"\n").c_str());
910 for (
auto it=vbcc.begin(); it<vbcc.end(); it++)
911 fprintf(pipe,
"%s", (
"~b"+*it+
"\n").c_str());
912 for (
auto it=vcc.begin(); it<vcc.end(); it++)
913 fprintf(pipe,
"%s", (
"~c"+*it+
"\n").c_str());
914 for (
auto it=vatt.begin(); it<vatt.end(); it++)
915 fprintf(pipe,
"%s", (
"~@"+*it+
"\n").c_str());
917 for (
auto it=vtxt.begin(); it<vtxt.end(); it++)
918 fwrite((*it+
"\n").c_str(), it->length()+1, 1, pipe);
920 fprintf(pipe,
"\n---\nsent by dimctrl");
925 const int rc = pclose(pipe);
928 return handle_scope.Close(Integer::New(WEXITSTATUS(rc)));
935 Handle<Value> InterpreterV8::ConstructorCurl(
const Arguments &args)
937 if (!args.IsConstructCall())
938 return ThrowException(String::New(
"Curl must be called as constructor"));
940 if (args.Length()!=1 || !args[0]->IsString())
941 return ThrowException(String::New(
"Constructor must be called with a single string as argument"));
943 HandleScope handle_scope;
945 Handle<Array>
data = Array::New();
949 Handle<Object>
self = args.This();
951 self->Set(String::New(
"url"), args[0]->ToString(), ReadOnly);
952 self->Set(String::New(
"data"), data, ReadOnly);
954 self->Set(String::New(
"send"), FunctionTemplate::New(WrapSendCurl)->GetFunction(), ReadOnly);
956 return handle_scope.Close(
self);
959 Handle<Value> InterpreterV8::FuncSendCurl(
const Arguments& args)
961 HandleScope handle_scope;
964 return ThrowException(String::New(
"Only one argument allowed."));
966 if (args.Length()==1 && !args[0]->IsBoolean())
967 return ThrowException(String::New(
"Argument must be a boolean."));
969 const bool block = args.Length()==0 || args[0]->BooleanValue();
971 const Handle<Value> url = args.This()->Get(String::New(
"url"));
972 const Handle<Value> data = args.This()->Get(String::New(
"data"));
974 const vector<string> vdata = ValueToArray(data);
975 const string sdata = boost::algorithm::join(vdata,
"&");
977 const string surl = *String::AsciiValue(url->ToString());
979 string cmd =
"curl -sSf ";
981 cmd +=
"--data '"+sdata+
"' ";
982 cmd +=
"'http://"+surl+
"' 2>&1 ";
984 FILE *pipe = popen(cmd.c_str(),
"r");
986 return ThrowException(String::New(strerror(errno)));
996 if (fgets(buf, 1024, pipe)==NULL)
1001 const int rc = pclose(pipe);
1003 Handle<Object> obj = Object::New();
1005 obj->Set(String::New(
"cmd"), String::New(cmd.c_str()));
1006 obj->Set(String::New(
"data"), String::New(txt.c_str()));
1007 obj->Set(String::New(
"rc"), Integer::NewFromUnsigned(WEXITSTATUS(rc)));
1010 return handle_scope.Close(obj);
1017 Handle<Value> InterpreterV8::FuncDbClose(
const Arguments &args)
1019 void *ptr = External::Unwrap(args.This()->GetInternalField(0));
1021 return Boolean::New(
false);
1025 auto it = find(fDatabases.begin(), fDatabases.end(), db);
1026 fDatabases.erase(it);
1030 HandleScope handle_scope;
1032 args.This()->SetInternalField(0, External::New(0));
1034 return handle_scope.Close(Boolean::New(
true));
1037 Handle<Value> InterpreterV8::FuncDbQuery(
const Arguments &args)
1039 if (args.Length()==0)
1040 return ThrowException(String::New(
"Arguments expected."));
1042 void *ptr = External::Unwrap(args.This()->GetInternalField(0));
1047 for (
int i=0; i<args.Length(); i++)
1048 query +=
string(
" ") + *String::AsciiValue(args[i]);
1054 HandleScope handle_scope;
1058 const mysqlpp::StoreQueryResult res = db->query(query).store();
1060 Handle<Array> ret = Array::New();
1064 ret->Set(String::New(
"table"), String::New(res.table()), ReadOnly);
1065 ret->Set(String::New(
"query"), String::New(query.c_str()), ReadOnly);
1067 Handle<Array> cols = Array::New();
1072 for (vector<mysqlpp::Row>::const_iterator it=res.begin(); it<res.end(); it++)
1074 Handle<Object> row = Object::New();
1078 const mysqlpp::FieldNames *list = it->field_list().list;
1080 for (
size_t i=0; i<it->size(); i++)
1082 const Handle<Value> name = String::New((*list)[i].c_str());
1086 if ((*it)[i].is_null())
1088 row->Set(name, Undefined(), ReadOnly);
1092 const string sql_type = (*it)[
i].type().sql_name();
1094 const bool uns = sql_type.find(
"UNSIGNED")==string::npos;
1096 if (sql_type.find(
"BIGINT")!=string::npos)
1100 const uint64_t val = (uint64_t)(*it)[
i];
1102 row->Set(name, Number::New(val), ReadOnly);
1104 row->Set(name, Integer::NewFromUnsigned(val), ReadOnly);
1108 const int64_t val = (int64_t)(*it)[
i];
1109 if (val<INT32_MIN || val>INT32_MAX)
1110 row->Set(name, Number::New(val), ReadOnly);
1112 row->Set(name, Integer::NewFromUnsigned(val), ReadOnly);
1118 if (sql_type.find(
"INT")!=string::npos)
1121 row->Set(name, Integer::NewFromUnsigned((uint32_t)(*it)[i]), ReadOnly);
1123 row->Set(name, Integer::New((int32_t)(*it)[i]), ReadOnly);
1127 if (sql_type.find(
"BOOL")!=string::npos )
1129 row->Set(name, Boolean::New((
bool)(*it)[i]), ReadOnly);
1133 if (sql_type.find(
"FLOAT")!=string::npos)
1136 val << setprecision(7) << (float)(*it)[
i];
1137 row->Set(name, Number::New(stod(val.str())), ReadOnly);
1141 if (sql_type.find(
"DOUBLE")!=string::npos)
1143 row->Set(name, Number::New((
double)(*it)[i]), ReadOnly);
1147 if (sql_type.find(
"CHAR")!=string::npos ||
1148 sql_type.find(
"TEXT")!=string::npos)
1150 row->Set(name, String::New((
const char*)(*it)[i]), ReadOnly);
1155 if (sql_type.find(
"TIMESTAMP")!=string::npos)
1156 date = mysqlpp::Time((*it)[
i]);
1158 if (sql_type.find(
"DATETIME")!=string::npos)
1159 date = mysqlpp::DateTime((*it)[
i]);
1161 if (sql_type.find(
" DATE ")!=string::npos)
1162 date = mysqlpp::Date((*it)[
i]);
1172 row->Set(name, val, ReadOnly);
1176 ret->Set(irow++, row);
1180 ret->Set(String::New(
"cols"), cols, ReadOnly);
1182 return handle_scope.Close(ret);
1184 catch (
const exception &e)
1186 return ThrowException(String::New(e.what()));
1191 Handle<Value> InterpreterV8::FuncDatabase(
const Arguments &args)
1193 if (!args.IsConstructCall())
1194 return ThrowException(String::New(
"Database must be called as constructor."));
1196 if (args.Length()!=1)
1197 return ThrowException(String::New(
"Number of arguments must be 1."));
1199 if (!args[0]->IsString())
1200 return ThrowException(String::New(
"Argument 1 not a string."));
1205 HandleScope handle_scope;
1211 fDatabases.push_back(db);
1213 Handle<Object>
self = args.This();
1214 self->Set(String::New(
"user"), String::New(db->
user.c_str()), ReadOnly);
1215 self->Set(String::New(
"server"), String::New(db->
server.c_str()), ReadOnly);
1216 self->Set(String::New(
"database"), String::New(db->
db.c_str()), ReadOnly);
1217 self->Set(String::New(
"port"), db->
port==0?Undefined():Integer::NewFromUnsigned(db->
port), ReadOnly);
1218 self->Set(String::New(
"query"), FunctionTemplate::New(WrapDbQuery)->GetFunction(), ReadOnly);
1219 self->Set(String::New(
"close"), FunctionTemplate::New(WrapDbClose)->GetFunction(), ReadOnly);
1220 self->SetInternalField(0, External::New(db));
1222 return handle_scope.Close(
self);
1224 catch (
const exception &e)
1226 return ThrowException(String::New(e.what()));
1235 Handle<Value> InterpreterV8::Convert(
char type,
const char* &ptr)
1245 val << setprecision(7) << *reinterpret_cast<const float*>(ptr);
1247 return Number::New(stod(val.str()));
1249 case 'D': { Handle<Value> v=Number::New(*reinterpret_cast<const double*>(ptr)); ptr+=8;
return v; }
1251 case 'L': { Handle<Value> v=Integer::NewFromUnsigned(*reinterpret_cast<const uint32_t*>(ptr)); ptr += 4;
return v; }
1254 const int64_t val = *
reinterpret_cast<const int64_t*
>(ptr);
1256 if (val>=0 && val<=UINT32_MAX)
1257 return Integer::NewFromUnsigned(val);
1258 if (val>=INT32_MIN && val<0)
1259 return Integer::New(val);
1260 return Number::New(val);
1262 case 'S': { Handle<Value> v=Integer::NewFromUnsigned(*reinterpret_cast<const uint16_t*>(ptr)); ptr += 2;
return v; }
1263 case 'C': { Handle<Value> v=Integer::NewFromUnsigned((uint16_t)*reinterpret_cast<const uint8_t*>(ptr)); ptr += 1;
return v; }
1268 Handle<Value> InterpreterV8::FuncClose(
const Arguments &args)
1270 HandleScope handle_scope;
1274 const String::AsciiValue
str(args.This()->Get(String::New(
"name")));
1276 const auto it = fReverseMap.find(*str);
1277 if (it!=fReverseMap.end())
1279 it->second.Dispose();
1280 fReverseMap.erase(it);
1283 args.This()->Set(String::New(
"isOpen"), Boolean::New(
false), ReadOnly);
1285 return handle_scope.Close(Boolean::New(JsUnsubscribe(*str)));
1288 Handle<Value> InterpreterV8::ConvertEvent(
const EventImp *evt, uint64_t
counter,
const char *str)
1290 const vector<Description> vec = JsDescription(str);
1292 Handle<Object> ret = fTemplateEvent->GetFunction()->NewInstance();
1300 ret->Set(String::New(
"name"), String::New(str), ReadOnly);
1301 ret->Set(String::New(
"format"), String::New(evt->
GetFormat().c_str()), ReadOnly);
1302 ret->Set(String::New(
"qos"), Integer::New(evt->
GetQoS()), ReadOnly);
1303 ret->Set(String::New(
"size"), Integer::New(evt->
GetSize()), ReadOnly);
1304 ret->Set(String::New(
"counter"), Integer::New(counter), ReadOnly);
1306 ret->Set(String::New(
"time"), date, ReadOnly);
1314 Handle<Object> named = Object::New();
1316 ret->Set(String::New(
"obj"), named, ReadOnly);
1330 ret->Set(String::New(
"data"), Null(), ReadOnly);
1338 typedef boost::char_separator<char> separator;
1339 const boost::tokenizer<separator> tokenizer(fmt, separator(
";:"));
1341 const vector<string> tok(tokenizer.begin(), tokenizer.end());
1343 Handle<Object> arr = tok.size()>1 ? Array::New() : ret;
1347 const char *ptr = evt->
GetText();
1353 for (
auto it=tok.begin(); it<tok.end() && ptr<
end; it++, pos++)
1355 char type = (*it)[0];
1358 string name = pos<vec.size() ? vec[pos].name :
"";
1367 case 'D': sz = 8;
break;
1370 case 'L': sz = 4;
break;
1371 case 'S': sz = 2;
break;
1372 case 'C': sz = 1;
break;
1377 if (it==tok.end() && (end-ptr)%sz>0)
1382 const uint32_t cnt = it==tok.end() ? (end-ptr)/sz : stoi(it->c_str());
1386 const bool is_str = type==
'C' && it==tok.end();
1387 const bool is_one = cnt==1 && it!=tok.end();
1392 v = String::New(ptr);
1394 v = Convert(type, ptr);
1397 if (!is_str && !is_one)
1399 Handle<Object> a = Array::New(cnt);
1403 for (uint32_t i=0; i<cnt; i++)
1404 a->Set(i, Convert(type, ptr));
1412 ret->Set(String::New(
"data"), v, ReadOnly);
1416 const Handle<String> n = String::New(name.c_str());
1422 ret->Set(String::New(
"data"), arr, ReadOnly);
1451 Handle<Value> InterpreterV8::FuncGetData(
const Arguments &args)
1453 if (args.Length()>2)
1454 return ThrowException(String::New(
"Number of arguments must not be greater than 2."));
1456 if (args.Length()>=1 && !args[0]->IsInt32() && !args[0]->IsNull())
1457 return ThrowException(String::New(
"Argument 1 not an uint32."));
1459 if (args.Length()==2 && !args[1]->IsBoolean())
1460 return ThrowException(String::New(
"Argument 2 not a boolean."));
1464 const bool null = args.Length()>=1 && args[0]->IsNull();
1465 const int32_t timeout = args.Length()>=1 ? args[0]->Int32Value() : 0;
1466 const bool named = args.Length()<2 || args[1]->BooleanValue();
1468 HandleScope handle_scope;
1470 const Handle<String> data = String::New(
"data");
1471 const Handle<String>
object = String::New(
"obj");
1473 const String::AsciiValue name(args.Holder()->Get(String::New(
"name")));
1478 while (!exception.HasCaught())
1480 const pair<uint64_t, EventImp *> p = JsGetEvent(*name);
1485 const Handle<Value> val = ConvertEvent(evt, p.first, *name);
1486 if (val->IsNativeError())
1487 return ThrowException(val);
1490 if (val->IsObject())
1492 const Handle<Object>
event = val->ToObject();
1493 const Handle<Value> obj =
event->Get(named?
object:data);
1499 if (!obj->IsUndefined())
1500 return handle_scope.Close(val);
1505 if (obj->IsObject() && obj->ToObject()->GetOwnPropertyNames()->Length()>0)
1506 return handle_scope.Close(val);
1512 if (args.Length()==0)
1515 if (!null &&
Time()-t>=boost::posix_time::milliseconds(abs(timeout)))
1526 if (exception.HasCaught())
1527 return exception.ReThrow();
1532 const string str =
"Waiting for a valid event of "+string(*name)+
" timed out.";
1533 return ThrowException(String::New(str.c_str()));
1543 const Locker locker;
1548 const auto it = fReverseMap.find(service);
1549 if (it==fReverseMap.end())
1552 const HandleScope handle_scope;
1554 Handle<Object> obj = it->second;
1556 const Handle<String> onchange = String::New(
"onchange");
1557 if (!obj->Has(onchange))
1560 const Handle<Value> val = obj->Get(onchange);
1561 if (!val->IsFunction())
1564 obj->CreationContext()->Enter();
1570 const int id = V8::GetCurrentThreadId();
1571 fThreadIds.insert(
id);
1573 Handle<Value> ret = ConvertEvent(&evt, cnt, service.c_str());
1574 if (ret->IsObject())
1575 Handle<Function>::Cast(val)->Call(obj, 1, &ret);
1577 fThreadIds.erase(
id);
1579 if (!HandleException(exception,
"Service.onchange"))
1580 V8::TerminateExecution(fThreadId);
1582 if (ret->IsNativeError())
1584 JsException(service+
".onchange callback - "+*String::AsciiValue(ret));
1585 V8::TerminateExecution(fThreadId);
1588 obj->CreationContext()->Exit();
1594 const string server = *String::AsciiValue(prop);
1595 auto it = fStateCallbacks.find(server);
1597 if (it!=fStateCallbacks.end())
1599 it->second.Dispose();
1600 fStateCallbacks.erase(it);
1603 if (value->IsFunction())
1604 fStateCallbacks[server] = Persistent<Object>::New(value->ToObject());
1606 return Handle<Value>();
1613 const Locker locker;
1618 auto it = fStateCallbacks.find(server);
1619 if (it==fStateCallbacks.end())
1621 it = fStateCallbacks.find(
"*");
1622 if (it==fStateCallbacks.end())
1626 const HandleScope handle_scope;
1628 it->second->CreationContext()->Enter();
1632 Handle<ObjectTemplate> obj = ObjectTemplate::New();
1633 obj->Set(String::New(
"server"), String::New(server.c_str()), ReadOnly);
1635 if (state.
index>-256)
1637 obj->Set(String::New(
"index"), Integer::New(state.
index), ReadOnly);
1638 obj->Set(String::New(
"name"), String::New(state.
name.c_str()), ReadOnly);
1639 obj->Set(String::New(
"comment"), String::New(state.
comment.c_str()), ReadOnly);
1641 if (!date.IsEmpty())
1642 obj->Set(String::New(
"time"), date);
1649 const int id = V8::GetCurrentThreadId();
1650 fThreadIds.insert(
id);
1652 Handle<Value> args[] = { obj->NewInstance() };
1653 Handle<Function> fun = Handle<Function>(Function::Cast(*it->second));
1654 fun->Call(fun, 1, args);
1656 fThreadIds.erase(
id);
1658 if (!HandleException(exception,
"dim.onchange"))
1659 V8::TerminateExecution(fThreadId);
1661 it->second->CreationContext()->Exit();
1668 Handle<Value> InterpreterV8::FuncSetInterrupt(
const Arguments &args)
1670 if (args.Length()!=1)
1671 return ThrowException(String::New(
"Number of arguments must be 1."));
1673 if (!args[0]->IsNull() && !args[0]->IsUndefined() && !args[0]->IsFunction())
1674 return ThrowException(String::New(
"Argument not a function, null or undefined."));
1676 if (args[0]->IsNull() || args[0]->IsUndefined())
1678 fInterruptCallback.Dispose();
1679 fInterruptCallback.Clear();
1684 fInterruptCallback = Persistent<Object>::New(args[0]->ToObject());
1690 if (fInterruptCallback.IsEmpty())
1691 return Handle<Value>();
1693 const size_t p = str.find_last_of(
'\n');
1695 const string usr = p==string::npos?
"":str.substr(p+1);
1697 string irq = p==string::npos?str:str.substr(0, p);
1698 const map<string,string> data =
Tools::Split(irq,
true);
1703 Handle<Object> arr = Array::New(data.size());
1705 if (date.IsEmpty() || arr.IsEmpty())
1706 return Handle<Value>();
1708 for (
auto it=data.begin(); it!=data.end(); it++)
1709 arr->Set(String::New(it->first.c_str()), String::New(it->second.c_str()));
1711 Handle<Value> args[] = { irq_str, arr, date, usr_str };
1712 Handle<Function> fun = Handle<Function>(Function::Cast(*fInterruptCallback));
1714 return fun->Call(fun, 4, args);
1721 const Locker locker;
1723 if (fThreadId<0 || fInterruptCallback.IsEmpty())
1726 const HandleScope handle_scope;
1728 fInterruptCallback->CreationContext()->Enter();
1734 const int id = V8::GetCurrentThreadId();
1735 fThreadIds.insert(
id);
1739 fThreadIds.erase(
id);
1741 const int rc = !val.IsEmpty() && val->IsInt32() ? val->Int32Value() : 0;
1743 if (!HandleException(exception,
"interrupt"))
1744 V8::TerminateExecution(fThreadId);
1746 fInterruptCallback->CreationContext()->Exit();
1748 return rc<10 || rc>255 ? -42 : rc;
1751 Handle<Value> InterpreterV8::FuncTriggerInterrupt(
const Arguments &args)
1754 for (
int i=0; i<args.Length(); i++)
1756 const String::AsciiValue
str(args[i]);
1758 if (
string(*str).find_first_of(
'\n')!=string::npos)
1759 return ThrowException(String::New(
"No argument must contain line breaks."));
1768 HandleScope handle_scope;
1770 const Handle<Value> rc = HandleInterruptImp(
Tools::Trim(data),
Time().JavaDate());
1771 return handle_scope.Close(rc);
1778 Handle<Value> InterpreterV8::FuncSubscription(
const Arguments &args)
1780 if (args.Length()!=1 && args.Length()!=2)
1781 return ThrowException(String::New(
"Number of arguments must be one or two."));
1783 if (!args[0]->IsString())
1784 return ThrowException(String::New(
"Argument 1 must be a string."));
1786 if (args.Length()==2 && !args[1]->IsFunction())
1787 return ThrowException(String::New(
"Argument 2 must be a function."));
1789 const String::AsciiValue
str(args[0]);
1791 if (!args.IsConstructCall())
1793 const auto it = fReverseMap.find(*str);
1794 if (it!=fReverseMap.end())
1800 const HandleScope handle_scope;
1802 Handle<Object>
self = args.This();
1803 self->Set(String::New(
"get"), FunctionTemplate::New(WrapGetData)->GetFunction(), ReadOnly);
1804 self->Set(String::New(
"close"), FunctionTemplate::New(WrapClose)->GetFunction(), ReadOnly);
1805 self->Set(String::New(
"name"), String::New(*str), ReadOnly);
1806 self->Set(String::New(
"isOpen"), Boolean::New(
true));
1808 if (args.Length()==2)
1809 self->Set(String::New(
"onchange"), args[1]);
1811 fReverseMap[*
str] = Persistent<Object>::New(
self);
1813 void *ptr = JsSubscribe(*str);
1815 return ThrowException(String::New((
"Subscription to '"+
string(*str)+
"' already exists.").c_str()));
1817 self->SetInternalField(0, External::New(ptr));
1831 double InterpreterV8::GetDataMember(
const Arguments &args,
const char *name)
1833 return args.This()->Get(String::New(name))->NumberValue();
1836 Handle<Value> InterpreterV8::CalcDist(
const Arguments &args,
const bool local)
1838 if (args.Length()!=2)
1839 return ThrowException(String::New(
"dist must not be called with two arguments."));
1841 if (!args[0]->IsObject() || !args[1]->IsObject())
1842 return ThrowException(String::New(
"at least one argument not an object."));
1844 HandleScope handle_scope;
1846 Handle<Object> obj[2] =
1848 Handle<Object>::Cast(args[0]),
1849 Handle<Object>::Cast(args[1])
1852 const Handle<String> s_theta = String::New(local?
"zd":
"dec");
1853 const Handle<String> s_phi = String::New(local?
"az":
"ra");
1855 const double conv_t = M_PI/180;
1856 const double conv_p = local ? -M_PI/180 : M_PI/12;
1857 const double offset = local ? 0 : M_PI;
1859 const double theta0 = offset - obj[0]->Get(s_theta)->NumberValue() * conv_t;
1860 const double phi0 = obj[0]->Get(s_phi )->NumberValue() * conv_p;
1861 const double theta1 = offset - obj[1]->Get(s_theta)->NumberValue() * conv_t;
1862 const double phi1 = obj[1]->Get(s_phi )->NumberValue() * conv_p;
1864 if (!finite(theta0) || !finite(theta1) || !finite(phi0) || !finite(phi1))
1865 return ThrowException(String::New(
"some values not valid or not finite."));
1881 const double x = sin(theta0) * sin(theta1) * cos(phi1-phi0);
1882 const double y = cos(theta0) * cos(theta1);
1884 const double res = acos(x + y) * 180/M_PI;
1886 return handle_scope.Close(Number::New(res));
1889 Handle<Value> InterpreterV8::LocalDist(
const Arguments &args)
1891 return CalcDist(args,
true);
1894 Handle<Value> InterpreterV8::SkyDist(
const Arguments &args)
1896 return CalcDist(args,
false);
1899 Handle<Value> InterpreterV8::MoonDisk(
const Arguments &args)
1901 if (args.Length()>1)
1902 return ThrowException(String::New(
"disk must not be called with more than one argument."));
1904 const uint64_t v = uint64_t(args[0]->NumberValue());
1905 const Time utc = args.Length()==0 ?
Time() :
Time(v/1000, v%1000);
1910 Handle<Value> InterpreterV8::LocalToSky(
const Arguments &args)
1912 if (args.Length()>1)
1913 return ThrowException(String::New(
"toSky must not be called with more than one argument."));
1915 if (args.Length()==1 && !args[0]->IsDate())
1916 return ThrowException(String::New(
"Argument must be a Date"));
1919 hrz.
zd = GetDataMember(args,
"zd");
1920 hrz.
az = GetDataMember(args,
"az");
1922 if (!finite(hrz.
zd) || !finite(hrz.
az))
1923 return ThrowException(String::New(
"zd and az must be finite."));
1925 HandleScope handle_scope;
1928 args.Length()==0 ? Date::New(
Time().JavaDate()) : args[0];
1932 const uint64_t v = uint64_t(date->NumberValue());
1933 const Time utc(v/1000, v%1000);
1939 Handle<Value> arg[] = { Number::New(equ.ra/15), Number::New(equ.dec), date };
1940 return handle_scope.Close(fTemplateSky->GetFunction()->NewInstance(3, arg));
1943 Handle<Value> InterpreterV8::SkyToLocal(
const Arguments &args)
1945 if (args.Length()>1)
1946 return ThrowException(String::New(
"toLocal must not be called with more than one argument."));
1948 if (args.Length()==1 && !args[0]->IsDate())
1949 return ThrowException(String::New(
"Argument must be a Date"));
1952 equ.ra = GetDataMember(args,
"ra")*15;
1953 equ.dec = GetDataMember(args,
"dec");
1955 if (!finite(equ.ra) || !finite(equ.dec))
1956 return ThrowException(String::New(
"Ra and dec must be finite."));
1958 HandleScope handle_scope;
1961 args.Length()==0 ? Date::New(
Time().JavaDate()) : args[0];
1965 const uint64_t v = uint64_t(date->NumberValue());
1966 const Time utc(v/1000, v%1000);
1970 Handle<Value> arg[] = { Number::New(hrz.
zd), Number::New(hrz.
az), date };
1971 return handle_scope.Close(fTemplateLocal->GetFunction()->NewInstance(3, arg));
1974 Handle<Value> InterpreterV8::MoonToLocal(
const Arguments &args)
1976 if (args.Length()>0)
1977 return ThrowException(String::New(
"toLocal must not be called with arguments."));
1980 equ.ra = GetDataMember(args,
"ra")*15;
1981 equ.dec = GetDataMember(args,
"dec");
1983 if (!finite(equ.ra) || !finite(equ.dec))
1984 return ThrowException(String::New(
"ra and dec must be finite."));
1986 HandleScope handle_scope;
1988 const Local<Value> date = args.This()->Get(String::New(
"time"));
1989 if (date.IsEmpty() || date->IsUndefined() )
1992 const uint64_t v = uint64_t(date->NumberValue());
1993 const Time utc(v/1000, v%1000);
1997 Handle<Value> arg[] = { Number::New(hrz.
zd), Number::New(hrz.
az), date };
1998 return handle_scope.Close(fTemplateLocal->GetFunction()->NewInstance(3, arg));
2001 Handle<Value> InterpreterV8::ConstructorMoon(
const Arguments &args)
2003 if (args.Length()>1)
2004 return ThrowException(String::New(
"Moon constructor must not be called with more than one argument."));
2006 if (args.Length()==1 && !args[0]->IsDate())
2007 return ThrowException(String::New(
"Argument must be a Date"));
2009 HandleScope handle_scope;
2012 args.Length()==0 ? Date::New(
Time().JavaDate()) : args[0];
2016 const uint64_t v = uint64_t(date->NumberValue());
2017 const Time utc(v/1000, v%1000);
2023 if (!args.IsConstructCall())
2024 return handle_scope.Close(Constructor(args));
2026 Handle<Function>
function =
2027 FunctionTemplate::New(MoonToLocal)->GetFunction();
2028 if (
function.IsEmpty())
2031 Handle<Object>
self = args.This();
2032 self->Set(String::New(
"ra"), Number::New(equ.ra/15), ReadOnly);
2033 self->Set(String::New(
"dec"), Number::New(equ.dec), ReadOnly);
2034 self->Set(String::New(
"toLocal"),
function, ReadOnly);
2035 self->Set(String::New(
"time"), date, ReadOnly);
2037 return handle_scope.Close(
self);
2040 Handle<Value> InterpreterV8::ConstructorSky(
const Arguments &args)
2042 if (args.Length()<2 || args.Length()>3)
2043 return ThrowException(String::New(
"Sky constructor takes two or three arguments."));
2045 if (args.Length()==3 && !args[2]->IsDate())
2046 return ThrowException(String::New(
"Third argument must be a Date."));
2048 const double ra = args[0]->NumberValue();
2049 const double dec = args[1]->NumberValue();
2051 if (!finite(ra) || !finite(dec))
2052 return ThrowException(String::New(
"Both arguments to Sky must be valid numbers."));
2056 HandleScope handle_scope;
2058 if (!args.IsConstructCall())
2059 return handle_scope.Close(Constructor(args));
2061 Handle<Function>
function =
2062 FunctionTemplate::New(SkyToLocal)->GetFunction();
2063 if (
function.IsEmpty())
2066 Handle<Object>
self = args.This();
2067 self->Set(String::New(
"ra"), Number::New(ra), ReadOnly);
2068 self->Set(String::New(
"dec"), Number::New(dec), ReadOnly);
2069 self->Set(String::New(
"toLocal"),
function, ReadOnly);
2070 if (args.Length()==3)
2071 self->Set(String::New(
"time"), args[2], ReadOnly);
2073 return handle_scope.Close(
self);
2076 Handle<Value> InterpreterV8::ConstructorLocal(
const Arguments &args)
2078 if (args.Length()<2 || args.Length()>3)
2079 return ThrowException(String::New(
"Local constructor takes two or three arguments."));
2081 if (args.Length()==3 && !args[2]->IsDate())
2082 return ThrowException(String::New(
"Third argument must be a Date."));
2084 const double zd = args[0]->NumberValue();
2085 const double az = args[1]->NumberValue();
2087 if (!finite(zd) || !finite(az))
2088 return ThrowException(String::New(
"Both arguments to Local must be valid numbers."));
2092 HandleScope handle_scope;
2094 if (!args.IsConstructCall())
2095 return handle_scope.Close(Constructor(args));
2097 Handle<Function>
function =
2098 FunctionTemplate::New(LocalToSky)->GetFunction();
2099 if (
function.IsEmpty())
2102 Handle<Object>
self = args.This();
2103 self->Set(String::New(
"zd"), Number::New(zd), ReadOnly);
2104 self->Set(String::New(
"az"), Number::New(az), ReadOnly);
2105 self->Set(String::New(
"toSky"),
function, ReadOnly);
2106 if (args.Length()==3)
2107 self->Set(String::New(
"time"), args[2], ReadOnly);
2109 return handle_scope.Close(
self);
2112 Handle<Object> InterpreterV8::ConstructRiseSet(
const Handle<Value> time,
const Nova::RstTime &rst,
const bool &rc)
2114 Handle<Object> obj = Object::New();
2115 obj->Set(String::New(
"time"), time, ReadOnly);
2117 const uint64_t v = uint64_t(time->NumberValue());
2118 const double jd =
Time(v/1000, v%1000).
JD();
2120 const bool isUp = rc>0 ||
2121 (rst.rise<rst.set && (jd>rst.rise && jd<rst.set)) ||
2122 (rst.rise>rst.set && (jd<rst.set || jd>rst.rise));
2124 obj->Set(String::New(
"isUp"), Boolean::New(rc>=0 && isUp), ReadOnly);
2129 Handle<Value> rise = Date::New(
Time(rst.rise).
JavaDate());
2130 Handle<Value>
set = Date::New(
Time(rst.set).
JavaDate());
2131 Handle<Value> trans = Date::New(
Time(rst.transit).
JavaDate());
2132 if (rise.IsEmpty() ||
set.IsEmpty() || trans.IsEmpty())
2133 return Handle<Object>();
2135 obj->Set(String::New(
"rise"), rise, ReadOnly);
2136 obj->Set(String::New(
"set"),
set, ReadOnly);
2137 obj->Set(String::New(
"transit"), trans, ReadOnly);
2142 Handle<Value> InterpreterV8::SunHorizon(
const Arguments &args)
2144 if (args.Length()>2)
2145 return ThrowException(String::New(
"Sun.horizon must not be called with one or two arguments."));
2147 if (args.Length()==2 && !args[1]->IsDate())
2148 return ThrowException(String::New(
"Second argument must be a Date"));
2150 HandleScope handle_scope;
2153 if (args.Length()==0 || args[0]->IsNull())
2154 hrz = LN_SOLAR_STANDART_HORIZON;
2155 if (args.Length()>0 && args[0]->IsNumber())
2156 hrz = args[0]->NumberValue();
2157 if (args.Length()>0 && args[0]->IsString())
2159 string arg(
Tools::Trim(*String::AsciiValue(args[0])));
2160 transform(arg.begin(), arg.end(), arg.begin(), ::tolower);
2162 if (arg==
string(
"horizon").substr(0, arg.length()))
2163 hrz = LN_SOLAR_STANDART_HORIZON;
2164 if (arg==
string(
"civil").substr(0, arg.length()))
2165 hrz = LN_SOLAR_CIVIL_HORIZON;
2166 if (arg==
string(
"nautical").substr(0, arg.length()))
2167 hrz = LN_SOLAR_NAUTIC_HORIZON;
2168 if (arg==
string(
"fact").substr(0, arg.length()))
2170 if (arg==
string(
"astronomical").substr(0, arg.length()))
2171 hrz = LN_SOLAR_ASTRONOMICAL_HORIZON;
2175 return ThrowException(String::New(
"Second argument did not yield a valid number."));
2178 args.Length()<2 ? Date::New(
Time().JavaDate()) : args[1];
2182 const uint64_t v = uint64_t(date->NumberValue());
2183 const Time utc(v/1000, v%1000);
2188 const int rc = ln_get_solar_rst_horizon(utc.
JD()-0.5, &obs, hrz, &sun);
2189 Handle<Object> rst = ConstructRiseSet(date, sun, rc);
2190 rst->Set(String::New(
"horizon"), Number::New(hrz));
2191 return handle_scope.Close(rst);
2194 Handle<Value> InterpreterV8::MoonHorizon(
const Arguments &args)
2196 if (args.Length()>1)
2197 return ThrowException(String::New(
"Moon.horizon must not be called with one argument."));
2199 if (args.Length()==1 && !args[0]->IsDate())
2200 return ThrowException(String::New(
"Argument must be a Date"));
2202 HandleScope handle_scope;
2205 args.Length()==0 ? Date::New(
Time().JavaDate()) : args[0];
2209 const uint64_t v = uint64_t(date->NumberValue());
2210 const Time utc(v/1000, v%1000);
2215 const int rc = ln_get_lunar_rst(utc.
JD()-0.5, &obs, &moon);
2216 Handle<Object> rst = ConstructRiseSet(date, moon, rc);
2217 return handle_scope.Close(rst);
2225 bool InterpreterV8::HandleException(TryCatch& try_catch,
const char *where)
2227 if (!try_catch.HasCaught() || !try_catch.CanContinue())
2230 const HandleScope handle_scope;
2232 Handle<Value> except = try_catch.Exception();
2233 if (except.IsEmpty() || except->IsNull())
2236 const String::AsciiValue exception(except);
2238 const Handle<Message>
message = try_catch.Message();
2239 if (message.IsEmpty())
2244 if (!message->GetScriptResourceName()->IsUndefined())
2247 const String::AsciiValue filename(message->GetScriptResourceName());
2248 if (filename.length()>0)
2251 if (message->GetLineNumber()>0)
2252 out <<
": l." << message->GetLineNumber();
2261 out <<
" [" << where <<
"]";
2263 JsException(out.str());
2266 const String::AsciiValue sourceline(message->GetSourceLine());
2268 JsException(*sourceline);
2271 const int start = message->GetStartColumn();
2272 const int end = message->GetEndColumn();
2276 out << setfill(
' ') << setw(start) <<
' ';
2277 out << setfill(
'^') << setw(end-start) <<
'^';
2279 JsException(out.str());
2281 const String::AsciiValue stack_trace(try_catch.StackTrace());
2282 if (stack_trace.length()<=0)
2288 const string trace(*stack_trace);
2290 typedef boost::char_separator<char> separator;
2291 const boost::tokenizer<separator> tokenizer(trace, separator(
"\n"));
2296 auto it = tokenizer.begin();
2298 while (it!=tokenizer.end())
2304 Handle<Value> InterpreterV8::ExecuteInternal(
const string &code)
2311 const Handle<Value> result = ExecuteCode(code);
2315 if (exception.HasCaught())
2316 exception.ReThrow();
2321 Handle<Value> InterpreterV8::ExecuteCode(
const string &code,
const string &file)
2323 HandleScope handle_scope;
2325 const Handle<String> source = String::New(code.c_str(), code.size());
2326 const Handle<String> origin = String::New(file.c_str());
2327 if (source.IsEmpty())
2330 const Handle<Script> script = Script::Compile(source, origin);
2331 if (script.IsEmpty())
2334 const Handle<String> __date__ = String::New(
"__DATE__");
2335 const Handle<String> __file__ = String::New(
"__FILE__");
2337 Handle<Value> save_date;
2338 Handle<Value> save_file;
2340 Handle<Object> global = Context::GetCurrent()->Global();
2341 if (!global.IsEmpty())
2344 if (stat(file.c_str(), &attrib)==0)
2346 save_date = global->Get(__date__);
2347 save_file = global->Get(__file__);
2349 global->Set(__file__, String::New(file.c_str()));
2351 const Local<Value> date = Date::New(attrib.st_mtime*1000);
2352 if (!date.IsEmpty())
2353 global->Set(__date__, date);
2357 const Handle<Value> rc = script->Run();
2361 if (!global.IsEmpty() && !save_date.IsEmpty())
2363 global->ForceSet(__date__, save_date);
2364 global->ForceSet(__file__, save_file);
2367 return handle_scope.Close(rc);
2370 void InterpreterV8::ExecuteConsole()
2375 lout <<
"\n " <<
kUnderline <<
" JavaScript interpreter " <<
kReset <<
" (enter '.q' to quit)\n" << endl;
2384 const HandleScope handle_scope;
2387 const Unlocker global_unlock;
2398 if (!command.empty())
2403 auto back = command.rbegin();
2418 const Handle<Value> rc = ExecuteCode(command,
"console");
2422 if (!rc->IsUndefined() && !rc->IsFunction())
2423 JsResult(*String::AsciiValue(rc));
2425 if (!HandleException(exception,
"console"))
2429 for (
auto it=fThreadIds.begin(); it!=fThreadIds.end(); it++)
2430 V8::TerminateExecution(*it);
2436 while (!fThreadIds.empty())
2454 const string ver(V8::GetVersion());
2456 typedef boost::char_separator<char> separator;
2457 const boost::tokenizer<separator> tokenizer(ver, separator(
"."));
2459 const vector<string> tok(tokenizer.begin(), tokenizer.end());
2461 const int major = tok.size()>0 ? stol(tok[0]) : -1;
2462 const int minor = tok.size()>1 ? stol(tok[1]) : -1;
2463 const int build = tok.size()>2 ? stol(tok[2]) : -1;
2465 if (major>3 || (major==3 && minor>9) || (major==3 && minor==9 && build>10))
2467 const string argv =
"--use_strict";
2468 V8::SetFlagsFromString(argv.c_str(), argv.size());
2482 Handle<Value> InterpreterV8::Constructor(
const Arguments &args)
2484 Handle<Value> argv[args.Length()];
2486 for (
int i=0; i<args.Length(); i++)
2489 return args.Callee()->NewInstance(args.Length(), argv);
2496 "String.form = function(str, arr)" 2499 "function callback(exp, p0, p1, p2, p3, p4/*, pos, str*/)" 2504 "if (arr[++i]===undefined)" 2507 "var exp = p2 ? parseInt(p2.substr(1)) : undefined;" 2508 "var base = p3 ? parseInt(p3.substr(1)) : undefined;" 2513 "case 's': val = arr[i]; break;" 2514 "case 'c': val = arr[i][0]; break;" 2515 "case 'f': val = parseFloat(arr[i]).toFixed(exp); break;" 2516 "case 'p': val = parseFloat(arr[i]).toPrecision(exp); break;" 2517 "case 'e': val = parseFloat(arr[i]).toExponential(exp); break;" 2518 "case 'x': val = parseInt(arr[i]).toString(base?base:16); break;" 2519 "case 'd': val = parseFloat(parseInt(arr[i], base?base:10).toPrecision(exp)).toFixed(0); break;" 2524 "val = typeof(val)=='object' ? JSON.stringify(val) : val.toString(base);" 2526 "var sz = parseInt(p1); /* padding size */" 2527 "var ch = p1 && p1[0]=='0' ? '0' : ' '; /* isnull? */" 2528 "while (val.length<sz)" 2529 "val = p0 !== undefined ? val+ch : ch+val; /* isminus? */" 2534 "var regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd])/g;" 2535 "return str.replace(regex, callback);" 2538 "String.prototype.$ = function()" 2540 "return String.form(this, Array.prototype.slice.call(arguments));" 2543 "String.prototype.count = function(c,i)" 2545 "return (this.match(new RegExp(c,i?'gi':'g'))||[]).length;" 2555 Handle<Script> script = Script::New(String::New(code.c_str()), String::New(
"internal"));
2556 if (!script.IsEmpty())
2572 const Locker locker;
2573 fThreadId = V8::GetCurrentThreadId();
2575 JsPrint(
string(
"JavaScript Engine V8 ")+V8::GetVersion());
2579 const HandleScope handle_scope;
2582 Handle<ObjectTemplate> dim = ObjectTemplate::New();
2583 dim->Set(String::New(
"log"), FunctionTemplate::New(WrapLog), ReadOnly);
2584 dim->Set(String::New(
"alarm"), FunctionTemplate::New(WrapAlarm), ReadOnly);
2585 dim->Set(String::New(
"wait"), FunctionTemplate::New(WrapWait), ReadOnly);
2586 dim->Set(String::New(
"send"), FunctionTemplate::New(WrapSend), ReadOnly);
2587 dim->Set(String::New(
"state"), FunctionTemplate::New(WrapState), ReadOnly);
2589 dim->Set(String::New(
"getStates"), FunctionTemplate::New(WrapGetStates), ReadOnly);
2590 dim->Set(String::New(
"getDescription"), FunctionTemplate::New(WrapGetDescription), ReadOnly);
2591 dim->Set(String::New(
"getServices"), FunctionTemplate::New(WrapGetServices), ReadOnly);
2593 Handle<ObjectTemplate> dimctrl = ObjectTemplate::New();
2594 dimctrl->Set(String::New(
"defineState"), FunctionTemplate::New(WrapNewState), ReadOnly);
2595 dimctrl->Set(String::New(
"setState"), FunctionTemplate::New(WrapSetState), ReadOnly);
2596 dimctrl->Set(String::New(
"getState"), FunctionTemplate::New(WrapGetState), ReadOnly);
2597 dimctrl->Set(String::New(
"setInterruptHandler"), FunctionTemplate::New(WrapSetInterrupt), ReadOnly);
2598 dimctrl->Set(String::New(
"triggerInterrupt"), FunctionTemplate::New(WrapTriggerInterrupt), ReadOnly);
2600 Handle<ObjectTemplate> v8 = ObjectTemplate::New();
2601 v8->Set(String::New(
"sleep"), FunctionTemplate::New(WrapSleep), ReadOnly);
2602 v8->Set(String::New(
"timeout"), FunctionTemplate::New(WrapTimeout), ReadOnly);
2603 v8->Set(String::New(
"version"), String::New(V8::GetVersion()), ReadOnly);
2605 Handle<ObjectTemplate> console = ObjectTemplate::New();
2606 console->Set(String::New(
"out"), FunctionTemplate::New(WrapOut), ReadOnly);
2607 console->Set(String::New(
"warn"), FunctionTemplate::New(WrapWarn), ReadOnly);
2609 Handle<ObjectTemplate> onchange = ObjectTemplate::New();
2610 onchange->SetNamedPropertyHandler(OnChangeGet, WrapOnChangeSet);
2611 dim->Set(String::New(
"onchange"), onchange);
2613 Handle<ObjectTemplate> global = ObjectTemplate::New();
2614 global->Set(String::New(
"v8"), v8, ReadOnly);
2615 global->Set(String::New(
"dim"), dim, ReadOnly);
2616 global->Set(String::New(
"dimctrl"), dimctrl, ReadOnly);
2617 global->Set(String::New(
"console"), console, ReadOnly);
2618 global->Set(String::New(
"include"), FunctionTemplate::New(WrapInclude), ReadOnly);
2619 global->Set(String::New(
"exit"), FunctionTemplate::New(WrapExit), ReadOnly);
2621 Handle<FunctionTemplate> sub = FunctionTemplate::New(WrapSubscription);
2622 sub->SetClassName(String::New(
"Subscription"));
2623 sub->InstanceTemplate()->SetInternalFieldCount(1);
2624 global->Set(String::New(
"Subscription"), sub, ReadOnly);
2627 Handle<FunctionTemplate> db = FunctionTemplate::New(WrapDatabase);
2628 db->SetClassName(String::New(
"Database"));
2629 db->InstanceTemplate()->SetInternalFieldCount(1);
2630 global->Set(String::New(
"Database"), db, ReadOnly);
2633 Handle<FunctionTemplate> thread = FunctionTemplate::New(WrapThread);
2634 thread->SetClassName(String::New(
"Thread"));
2635 global->Set(String::New(
"Thread"), thread, ReadOnly);
2637 Handle<FunctionTemplate> file = FunctionTemplate::New(WrapFile);
2638 file->SetClassName(String::New(
"File"));
2639 global->Set(String::New(
"File"), file, ReadOnly);
2641 Handle<FunctionTemplate> evt = FunctionTemplate::New();
2642 evt->SetClassName(String::New(
"Event"));
2643 global->Set(String::New(
"Event"), evt, ReadOnly);
2645 Handle<FunctionTemplate> desc = FunctionTemplate::New();
2646 desc->SetClassName(String::New(
"Description"));
2647 global->Set(String::New(
"Description"), desc, ReadOnly);
2649 fTemplateEvent = evt;
2650 fTemplateDescription = desc;
2653 Handle<FunctionTemplate> mail = FunctionTemplate::New(ConstructorMail);
2654 mail->SetClassName(String::New(
"Mail"));
2655 global->Set(String::New(
"Mail"), mail, ReadOnly);
2659 Handle<FunctionTemplate> curl = FunctionTemplate::New(ConstructorCurl);
2660 mail->SetClassName(String::New(
"Curl"));
2661 global->Set(String::New(
"Curl"), curl, ReadOnly);
2665 Handle<FunctionTemplate> sky = FunctionTemplate::New(ConstructorSky);
2666 sky->SetClassName(String::New(
"Sky"));
2667 sky->Set(String::New(
"dist"), FunctionTemplate::New(SkyDist), ReadOnly);
2668 global->Set(String::New(
"Sky"), sky, ReadOnly);
2670 Handle<FunctionTemplate> loc = FunctionTemplate::New(ConstructorLocal);
2671 loc->SetClassName(String::New(
"Local"));
2672 loc->Set(String::New(
"dist"), FunctionTemplate::New(LocalDist), ReadOnly);
2673 global->Set(String::New(
"Local"), loc, ReadOnly);
2675 Handle<FunctionTemplate> moon = FunctionTemplate::New(ConstructorMoon);
2676 moon->SetClassName(String::New(
"Moon"));
2677 moon->Set(String::New(
"disk"), FunctionTemplate::New(MoonDisk), ReadOnly);
2678 moon->Set(String::New(
"horizon"), FunctionTemplate::New(MoonHorizon), ReadOnly);
2679 global->Set(String::New(
"Moon"), moon, ReadOnly);
2681 Handle<FunctionTemplate> sun = FunctionTemplate::New();
2682 sun->SetClassName(String::New(
"Sun"));
2683 sun->Set(String::New(
"horizon"), FunctionTemplate::New(SunHorizon), ReadOnly);
2684 global->Set(String::New(
"Sun"), sun, ReadOnly);
2686 fTemplateLocal = loc;
2691 Persistent<Context> context = Context::New(NULL, global);
2692 if (context.IsEmpty())
2694 JsException(
"Creation of global context failed...");
2700 context->AllowCodeGenerationFromStrings(
false);
2702 Context::Scope scope(context);
2704 Handle<Array> args = Array::New(map.size());
2705 for (
auto it=map.begin(); it!=map.end(); it++)
2706 args->Set(String::New(it->first.c_str()), String::New(it->second.c_str()));
2707 context->Global()->Set(String::New(
"$"), args, ReadOnly);
2708 context->Global()->Set(String::New(
"arg"), args, ReadOnly);
2711 if (!starttime.IsEmpty())
2712 context->Global()->Set(String::New(
"__START__"), starttime, ReadOnly);
2718 AddFormatToGlobal();
2720 if (!exception.HasCaught())
2724 Locker::StartPreemption(10);
2726 if (filename.empty())
2732 const Handle<String> source = String::New((
"include('"+filename+
"');").c_str());
2733 const Handle<String> origin = String::New(
"main");
2734 const Handle<Script> script = Script::Compile(source, origin);
2735 if (!script.IsEmpty())
2742 Locker::StopPreemption();
2745 for (
auto it=fThreadIds.begin(); it!=fThreadIds.end(); it++)
2746 V8::TerminateExecution(*it);
2751 HandleException(exception,
"main");
2776 for (
auto it=fThreads.begin(); it!=fThreads.end(); it++)
2782 for (
auto it=fStateCallbacks.begin(); it!=fStateCallbacks.end(); it++)
2783 it->second.Dispose();
2784 fStateCallbacks.clear();
2787 fInterruptCallback.Dispose();
2788 fInterruptCallback.Clear();
2791 for (
auto it=fReverseMap.begin(); it!=fReverseMap.end(); it++)
2792 it->second.Dispose();
2793 fReverseMap.clear();
2797 for (
auto it=fDatabases.begin(); it!=fDatabases.end(); it++)
2814 V8::TerminateExecution(This->fThreadId);
2821 rc.emplace_back(
"for (");
2822 rc.emplace_back(
"while (");
2823 rc.emplace_back(
"if (");
2824 rc.emplace_back(
"switch (");
2825 rc.emplace_back(
"case ");
2826 rc.emplace_back(
"var ");
2827 rc.emplace_back(
"function ");
2828 rc.emplace_back(
"Date(");
2829 rc.emplace_back(
"new Date(");
2830 rc.emplace_back(
"'use strict';");
2831 rc.emplace_back(
"undefined");
2832 rc.emplace_back(
"null");
2833 rc.emplace_back(
"delete ");
2835 rc.emplace_back(
"dim.log(");
2836 rc.emplace_back(
"dim.alarm(");
2837 rc.emplace_back(
"dim.wait(");
2838 rc.emplace_back(
"dim.send(");
2839 rc.emplace_back(
"dim.state(");
2840 rc.emplace_back(
"dim.version");
2841 rc.emplace_back(
"dim.getStates(");
2842 rc.emplace_back(
"dim.getDescription(");
2843 rc.emplace_back(
"dim.getServices(");
2845 rc.emplace_back(
"dimctrl.defineState(");
2846 rc.emplace_back(
"dimctrl.setState(");
2847 rc.emplace_back(
"dimctrl.getState(");
2848 rc.emplace_back(
"dimctrl.setInterruptHandler(");
2849 rc.emplace_back(
"dimctrl.triggerInterrupt(");
2851 rc.emplace_back(
"v8.sleep(");
2852 rc.emplace_back(
"v8.timeout(");
2853 rc.emplace_back(
"v8.version()");
2855 rc.emplace_back(
"console.out(");
2856 rc.emplace_back(
"console.warn(");
2858 rc.emplace_back(
"include(");
2859 rc.emplace_back(
"exit()");
2862 rc.emplace_back(
"Database(");
2863 rc.emplace_back(
"new Database(");
2865 rc.emplace_back(
".table");
2866 rc.emplace_back(
".user");
2867 rc.emplace_back(
".database");
2868 rc.emplace_back(
".port");
2869 rc.emplace_back(
".query");
2872 rc.emplace_back(
"Subscription(");
2873 rc.emplace_back(
"new Subscription(");
2875 rc.emplace_back(
"Thread(");
2876 rc.emplace_back(
"new Thread(");
2878 rc.emplace_back(
"File(");
2879 rc.emplace_back(
"new File(");
2881 rc.emplace_back(
"Event(");
2882 rc.emplace_back(
"new Event(");
2884 rc.emplace_back(
"Description(");
2885 rc.emplace_back(
"new Description(");
2888 rc.emplace_back(
"Mail(");
2889 rc.emplace_back(
"new Mail(");
2891 rc.emplace_back(
".subject");
2892 rc.emplace_back(
".receipients");
2893 rc.emplace_back(
".attachments");
2894 rc.emplace_back(
".bcc");
2895 rc.emplace_back(
".cc");
2896 rc.emplace_back(
".text");
2897 rc.emplace_back(
".send(");
2901 rc.emplace_back(
"Curl(");
2902 rc.emplace_back(
"new Curl(");
2904 rc.emplace_back(
".url");
2905 rc.emplace_back(
".user");
2906 rc.emplace_back(
".data");
2911 rc.emplace_back(
"Sky(");
2912 rc.emplace_back(
"new Sky(");
2914 rc.emplace_back(
"Sky.dist");
2915 rc.emplace_back(
"Local(");
2917 rc.emplace_back(
"new Local(");
2918 rc.emplace_back(
"Local.dist");
2920 rc.emplace_back(
"Moon(");
2921 rc.emplace_back(
"new Moon(");
2922 rc.emplace_back(
"Moon.disk(");
2923 rc.emplace_back(
"Moon.horizon(");
2925 rc.emplace_back(
"Sun.horizon(");
2927 rc.emplace_back(
".zd");
2928 rc.emplace_back(
".az");
2929 rc.emplace_back(
".ra");
2930 rc.emplace_back(
".dec");
2932 rc.emplace_back(
".toLocal(");
2933 rc.emplace_back(
".toSky(");
2934 rc.emplace_back(
".rise");
2935 rc.emplace_back(
".set");
2936 rc.emplace_back(
".transit");
2937 rc.emplace_back(
".isUp");
2939 rc.emplace_back(
"horizon");
2940 rc.emplace_back(
"civil");
2941 rc.emplace_back(
"nautical");
2942 rc.emplace_back(
"astronomical");
2945 rc.emplace_back(
".server");
2946 rc.emplace_back(
".service");
2947 rc.emplace_back(
".name");
2948 rc.emplace_back(
".isCommand");
2949 rc.emplace_back(
".format");
2950 rc.emplace_back(
".description");
2951 rc.emplace_back(
".unit");
2952 rc.emplace_back(
".delim");
2953 rc.emplace_back(
".isOpen");
2955 rc.emplace_back(
".qos");
2956 rc.emplace_back(
".size");
2957 rc.emplace_back(
".counter");
2958 rc.emplace_back(
".type");
2959 rc.emplace_back(
".obj");
2960 rc.emplace_back(
".data");
2961 rc.emplace_back(
".comment");
2962 rc.emplace_back(
".index");
2963 rc.emplace_back(
".time");
2964 rc.emplace_back(
".close()");
2965 rc.emplace_back(
".onchange");
2966 rc.emplace_back(
".get(");
2969 rc.emplace_back(
"__DATE__");
2970 rc.emplace_back(
"__FILE__");
void JsHandleState(const std::string &, const State &)
static v8::Handle< v8::FunctionTemplate > fTemplateEvent
static std::string StaticPrompt(const std::string &prompt)
uint64_t JavaDate() const
A general base-class describing events issues in a state machine.
const char * GetText() const
std::string comment
Name (e.g. 'Connected')
EquPosn GetLunarEquCoords(double jd, double precision=0)
Adds some functionality to boost::posix_time::ptime for our needs.
A C++ ostream to an ncurses window supporting attributes and colors.
static v8::Handle< v8::FunctionTemplate > fTemplateDescription
virtual void JsEnd(const std::string &="")
void JsHandleEvent(const EventImp &, uint64_t, const std::string &)
std::string GetString() const
double GetLunarDisk(double jd)
static void StaticPopHistory(const std::string &fname)
static void StaticPushHistory(const std::string &fname)
int JsHandleInterrupt(const EventImp &)
static v8::Handle< v8::FunctionTemplate > fTemplateLocal
static v8::Handle< v8::FunctionTemplate > fTemplateSky
static void SetScriptDepth(unsigned int d)
virtual std::string GetFormat() const
std::vector< std::string > JsGetCommandList(const char *, int) const
virtual int GetQoS() const
bool JsRun(const std::string &, const std::map< std::string, std::string > &=std::map< std::string, std::string >())
void Thread(MainImp *io_service, bool dummy, int &rc)
Warning because the service this data corrsponds to might have been last updated longer ago than Local time
uint64_t GetJavaDate() const
virtual void JsLoad(const std::string &="")
HrzPosn GetHrzFromEqu(const EquPosn &equ, const LnLatPosn &obs, double jd)
v8::Handle< v8::Value > HandleInterruptImp(std::string, uint64_t)
#define DIM_VERSION_NUMBER
EquPosn GetEquFromHrz(const HrzPosn &hrz, const LnLatPosn &obs, double jd)
std::string name
Index (e.g. 1)
Time time
Description (e.g. 'Connection to hardware established.')
virtual bool IsEmpty() const
static InterpreterV8 * This
virtual size_t GetSize() const