#include <cstring>
#include <sstream>
#include "var.h"
#include "blop_bookkeeper.h"
#include "graph_drawer.h"
#include "exc.H"
#include "function_core.H"
#include "function.h"
#include "cfunc_wrapper.H"
#include "cfunc_wrapper.h"
#ifdef CINT_INCLUDE_PREFIX
#include "cint/Api.h"
#else
#include "Api.h"
#endif
#include "fit.h"
#include "bloputils.h"
#include "plot.h"
using namespace std;
namespace blop
{
fgraph &plot(void *f1, void *f2, void *f3, void *f4, void *f5)
{
function f1_ = cfunc(f1);
function f2_ = (f2?cfunc(f2):function(unset));
function f3_ = (f3?cfunc(f3):function(unset));
function f4_ = (f4?cfunc(f4):function(unset));
function f5_ = (f5?cfunc(f5):function(unset));
return plot(f1_,f2_,f3_,f4_,f5_);
}
fgraph &plot(void *f1, const function &f2, void *f3, void *f4,void *f5)
{
function f1_ = cfunc(f1);
function f3_ = (f3?cfunc(f3):function(unset));
function f4_ = (f4?cfunc(f4):function(unset));
function f5_ = (f5?cfunc(f5):function(unset));
return plot(f1_,f2,f3_,f4_,f5_);
}
fgraph &plot(const function &f1, void *f2, void *f3, void *f4, void *f5)
{
function f2_ = cfunc(f2);
function f3_ = (f3?cfunc(f3):function(unset));
function f4_ = (f4?cfunc(f4):function(unset));
function f5_ = (f5?cfunc(f5):function(unset));
return plot(f1,f2_,f3_,f4_,f5_);
}
fgraph &mplot(void *f1, void *f2, void *f3, void *f4, void *f5)
{
function f1_ = cfunc(f1);
function f2_ = (f2?cfunc(f2):function(unset));
function f3_ = (f3?cfunc(f3):function(unset));
function f4_ = (f4?cfunc(f4):function(unset));
function f5_ = (f5?cfunc(f5):function(unset));
return mplot(f1_,f2_,f3_,f4_,f5_);
}
void blop_initializer::call_INIT()
{
G__ClassInfo globalscope;
G__MethodInfo method;
long dummy;
method = globalscope.GetMethod("BLOP_USER_INIT","",&dummy);
if(method.IsValid())
{
void *p2f = method.PointerToFunc();
int type = G__isinterpretedp2f(p2f);
if(type == G__BYTECODEFUNC || type == G__INTERPRETEDFUNC)
{
G__calc("BLOP_USER_INIT()");
}
}
}
color color_mapping::map_interpreted(double val,double mini,double maxi) const
{
var cmd = "color_mapping::the_color_ = ";
cmd &= fname_;
cmd &= "(";
cmd &= val;
cmd &= ",";
cmd &= mini;
cmd &= ",";
cmd &= maxi;
cmd &= ");";
G__calc(cmd.c_str());
return color_mapping::the_color_;
}
void color_mapping::set(void *pointer)
{
if(pointer == 0)
{
p2f_ = 0;
p2f_cint_ = 0;
fname_ = "this_should_not_happen";
return;
}
if(pointer == (void*)color_mapping::def)
{
p2f_ = color_mapping::def;
p2f_cint_ = 0;
fname_ = "this_should_not_happen";
return;
}
char *fname;
if((fname = G__p2f2funcname(pointer)) == 0)
{
warning::print("Unknown pointer to function in","color_mapping::set(void*)");
p2f_ = 0;
p2f_cint_ = 0;
fname_ = "this_should_not_happen";
return;
}
fname_ = fname;
G__ClassInfo globalscope;
G__MethodInfo method;
long dummy;
method = globalscope.GetMethod(fname,"double,double,double",&dummy);
if(!method.IsValid())
{
warning::print(var("Function '") & var(fname) &
var("(double,double,double)' is not found"));
p2f_ = 0;
p2f_cint_ = 0;
fname_ = "this_should_not_happen";
return;
}
pointer = method.PointerToFunc();
switch(G__isinterpretedp2f(pointer))
{
case G__BYTECODEFUNC:
case G__INTERPRETEDFUNC:
case G__COMPILEDINTERFACEMETHOD:
{
p2f_cint_ = pointer;
p2f_ = 0;
break;
}
case G__COMPILEDTRUEFUNC:
case G__UNKNOWNFUNC:
{
typedef color (*ppp)(double,double,double);
p2f_cint_ = 0;
p2f_ = (ppp)pointer;
break;
}
default:
err("This should never happen");
}
}
void function::formula(const var &f)
{
char ptr[30];
sprintf(ptr,"(*(function*)%p) = ",this);
var cmd = ptr;
cmd &= f;
G__exec_text(cmd.c_str());
}
void function_core::cfunc::init_(void *p)
{
wrapper_ = cfunc_wrapper_base::find(p);
if(wrapper_ == 0)
{
warning::print("No function found","function_core::cfunc::init_(void*)");
return;
}
if(wrapper_->n_args() <= 0 ||wrapper_->n_out() <= 0)
{
warning::print("This cfunc_wrapper is not prepared to work with function",
"function_core::cfunc::init(void *)");
delete wrapper_;
wrapper_ = 0;
return;
}
}
double double_func_aref_aref_aref_aref_aref
::operator() (const std::vector<blop::var> &a1,
const std::vector<blop::var> &a2,
const std::vector<blop::var> &a3,
const std::vector<blop::var> &a4,
const std::vector<blop::var> &a5)
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled) return (result_=((function_type)ptr_)(a1,a2,a3,a4,a5));
std::string cmd = fname_ + "(";
char buf[1000];
const char *t = "*(std::vector<blop::var>*)";
sprintf(buf,"%s%p,%s%p,%s%p,%s%p,%s%p", t,&a1, t,&a2, t,&a3, t,&a4, t,&a5);
cmd += buf;
cmd += ");";
result_ = G__double(G__calc(cmd.c_str()));
return result_;
}
double double_func_aref_aref_aref_aref_aref_aref
::operator() (const std::vector<blop::var> &a1,
const std::vector<blop::var> &a2,
const std::vector<blop::var> &a3,
const std::vector<blop::var> &a4,
const std::vector<blop::var> &a5,
const std::vector<blop::var> &a6)
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled) return (result_=((function_type)ptr_)(a1,a2,a3,a4,a5,a6));
std::string cmd = fname_ + "(";
char buf[1000];
const char *t = "*(std::vector<blop::var>*)";
sprintf(buf,"%s%p,%s%p,%s%p,%s%p,%s%p,%s%p", t,&a1, t,&a2, t,&a3, t,&a4, t,&a5, t,&a6);
cmd += buf;
cmd += ");";
result_ = G__double(G__calc(cmd.c_str()));
return result_;
}
double double_func_aref_aref_aref_aref_aref_aref_aref
::operator() (const std::vector<blop::var> &a1,
const std::vector<blop::var> &a2,
const std::vector<blop::var> &a3,
const std::vector<blop::var> &a4,
const std::vector<blop::var> &a5,
const std::vector<blop::var> &a6,
const std::vector<blop::var> &a7)
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled) return (result_=((function_type)ptr_)(a1,a2,a3,a4,a5,a6,a7));
std::string cmd = fname_ + "(";
char buf[1000];
const char *t = "*(std::vector<blop::var>*)";
sprintf(buf,"%s%p,%s%p,%s%p,%s%p,%s%p,%s%p,%s%p", t,&a1, t,&a2, t,&a3, t,&a4, t,&a5, t,&a6, t,&a7);
cmd += buf;
cmd += ");";
result_ = G__double(G__calc(cmd.c_str()));
return result_;
}
int int_func_double_double_aref_aref_int
::operator() (double a1, double a2,
const std::vector<blop::var> &a3,
const std::vector<blop::var> &a4,
int a5) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled) return (result_=((function_type)ptr_)(a1,a2,a3,a4,a5));
std::string cmd = fname_ + "(";
char buf[1000];
const char *t = "*(std::vector<blop::var>*)";
sprintf(buf,"*(double*)%p,*(double*)%p,%s%p,%s%p,*(int*)%p", &a1, &a2, t,&a3, t,&a4, &a5);
cmd += buf;
cmd += ");";
result_ = G__int(G__calc(cmd.c_str()));
return result_;
}
complex<double> complex_func_double::operator()(double v) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called",
"complex_func_double::operator()(double)");
return (result_=0);
}
if(functype_ == compiled)
{
return (result_=((function_type)ptr_)(v));
}
char cmd[1000];
sprintf(cmd,"temporary_result_complex = %s(%f);",fname_.c_str(),v);
G__calc(cmd);
return (result_=temporary_result_complex);
}
complex<double> complex_func_double_double::operator()(double v1,double v2) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called",
"complex_func_double_double::operator()(double,double)");
return (result_=0);
}
if(functype_ == compiled)
{
return (result_=((function_type)ptr_)(v1,v2));
}
char cmd[1000];
sprintf(cmd,"temporary_result_complex = %s(%f,%f);",fname_.c_str(),v1,v2);
G__calc(cmd);
return (result_=temporary_result_complex);
}
double double_func_double::operator()(double v) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called",
"double_func_double::operator()(double)");
return (result_=0);
}
if(functype_ == compiled) return (result_=((function_type)ptr_)(v));
var cmd = var(fname_) & "(" & v & ")";
result_ = G__double(G__calc(cmd.c_str()));
return result_;
}
double double_func_double_double::operator()(double v1,double v2) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled) return (result_=((function_type)ptr_)(v1,v2));
var cmd = var(fname_) & "(" & v1 & "," & v2 & ")";
result_ = G__double(G__calc(cmd.c_str()));
return result_;
}
double double_func_double_double_double::operator()(double v1,double v2,double v3) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled) return (result_=((function_type)ptr_)(v1,v2,v3));
var cmd = var(fname_) & "(" & v1 & "," & v2 & "," & v3 & ")";
result_ = G__double(G__calc(cmd.c_str()));
return result_;
}
double double_func_double_double_double_double::operator()(double v1,double v2,double v3,double v4) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled) return (result_=((function_type)ptr_)(v1,v2,v3,v4));
var cmd = var(fname_) & "(" & v1 & "," & v2 & "," & v3 & "," & v4 & ")";
result_ = G__double(G__calc(cmd.c_str()));
return result_;
}
var var_func_varvector_varvector::operator()(const std::vector<blop::var> &args,
const std::vector<blop::var> &pars) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled)
{
return (result_=((function_type)ptr_)(args,pars));
}
ostringstream ptr1, ptr2;
ptr1<<&args;
ptr2<<&pars;
var cmd = var("temporary_result_var = ") & fname_ & "(" &
var("*((const std::vector<blop::var> *)") & ptr1.str() & ")," &
var("*((const std::vector<blop::var> *)") & ptr2.str() & "))";
G__calc(cmd.c_str());
return (result_=temporary_result_var);
}
var var_func_var::operator()(var v) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled)
{
return (result_=((function_type)ptr_)(v));
}
var cmd = var("temporary_result_var = ") & fname_ & "(" & v & ")";
G__calc(cmd.c_str());
return (result_=temporary_result_var);
}
var var_func_var_var::operator()(var v1,var v2) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled) return (result_=((function_type)ptr_)(v1,v2));
var cmd = var("temporary_result_var = ") & fname_ & "(" & v1 & "," & v2 & ")";
G__calc(cmd.c_str());
return (result_=temporary_result_var);
}
var var_func_var_var_var::operator()(var v1,var v2,var v3) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled) return (result_=((function_type)ptr_)(v1,v2,v3));
var cmd = var("temporary_result_var = ") & fname_ & "(" & v1 & "," & v2 & "," & v3 & ")";
G__calc(cmd.c_str());
return (result_=temporary_result_var);
}
var var_func_var_var_var_var::operator()(var v1,var v2,var v3,var v4) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called");
return (result_=0);
}
if(functype_ == compiled) return (result_=((function_type)ptr_)(v1,v2,v3,v4));
var cmd = var("temporary_result_var = ") & fname_ & "(" & v1 & "," & v2 & "," & v3 & "," & v4 & ")";
G__calc(cmd.c_str());
return (result_=temporary_result_var);
}
void void_func_doublep_doublep::operator()(double *in, double *out) const
{
if(ptr_ == 0)
{
warning::print("Uninitialized cfunc_wrapper called","void_func_doublep_doublep::operator()");
result_ = 0;
return;
}
result_ = 1;
if(functype_ == compiled) { ((function_type)ptr_)(in,out); return; }
char cmd[1000];
sprintf(cmd,"%s((double*)%p,(double*)%p)",fname_.c_str(),in,out);
G__calc(cmd);
}
std::string create_arglist(G__MethodInfo &func)
{
string alist;
G__MethodArgInfo arg(func);
int count=0;
while(arg.Next())
{
if(count > 0) alist += ",";
long int property = arg.Property();
if((property&G__BIT_ISCONSTANT) &&
strstr(arg.Type()->Name(),"const ") != arg.Type()->Name())
{
alist += "const ";
}
alist += arg.Type()->Name();
++count;
}
return alist;
}
bool arglist_matches(var a1, var a2)
{
if(a1.str() == a2.str()) return true;
a1.replace("std::","");
a2.replace("std::","");
if(a1.str() == a2.str()) return true;
return false;
}
void cfunc_wrapper_base::find(void *pointer,
std::vector<G__MethodInfo> &results,
std::string &function_name_global,
const std::string &arglist_spec)
{
results.clear();
function_name_global = "UNKNOWN FUNCTION";
if(pointer == 0)
{
warning::print("0 pointer","cfunc_wrapper_base::find(...)");
return;
}
function_name_global = G__p2f2funcname(pointer);
if(function_name_global == "")
{
warning::print("Unknown pointer to function",
"cfunc_wrapper_base::find"
"(void *,const string &,int&,void*&,string&,string&)");
function_name_global == "UNKNOWN FUNCTION";
return;
}
std::string fname = function_name_global;
G__MethodInfo *method = 0;
G__ClassInfo *scope = 0;
string::size_type pos;
if( (pos = function_name_global.find("::")) != string::npos )
{
string classname = function_name_global.substr(0,pos);
scope = new G__ClassInfo(classname.c_str());
method = new G__MethodInfo(*scope);
fname = function_name_global.substr(pos+2);
}
else
{
method = new G__MethodInfo;
fname = function_name_global;
}
array arglists = split(arglist_spec,"|");
while(method->Next())
{
if(fname != method->Name()) continue;
if(arglists.empty())
{
results.push_back(*method);
continue;
}
std::string alist = create_arglist(*method);
for(unsigned int i=0; i<arglists.size(); ++i)
{
if(arglist_matches(arglists[i], alist))
{
results.push_back(*method);
break;
}
}
}
delete method;
delete scope;
}
cfunc_wrapper_base *cfunc_wrapper_base::find(void *pointer, const std::string &arglist_spec)
{
string function_name_global;
std::vector<G__MethodInfo> methods;
find(pointer,
methods,
function_name_global,
arglist_spec);
if(debug::on())
{
debug::print(var((long int)methods.size()) & var(" function candidates found!"),
var("cfunc_wrapper_base::find(void*,\"") &
arglist_spec &
var("\")"));
}
cfunc_wrapper_base *f = 0;
for(unsigned int i=0; i<methods.size(); ++i)
{
const string returntype = methods[i].Type()->Name();
int functype = G__isinterpretedp2f(methods[i].PointerToFunc());
const std::string arglist = create_arglist(methods[i]);
string ftmessage = string("Function: ") + returntype + " " + function_name_global +
"(" + arglist + ") [";
if(functype == G__COMPILEDTRUEFUNC
)
{
ftmessage += "compiled";
functype = compiled;
}
else
{
functype = interpreted;
ftmessage += "interpreted";
}
ftmessage += "]";
debug::print(ftmessage,"cfunc_wrapper_base::find(void*,string arglist)");
if(returntype == "double" && arglist == "double")
{
f = new double_func_double;
}
else if(returntype == "double" && arglist == "double,double")
{
f = new double_func_double_double;
}
else if(returntype == "double" && arglist == "double,double,double")
{
f = new double_func_double_double_double;
}
else if(returntype == "double" && arglist == "double,double,double,double")
{
f = new double_func_double_double_double_double;
}
else if((returntype == "var" || returntype == "blop::var") &&
(arglist == "var" || arglist == "blop::var"))
{
f = new var_func_var;
}
else if((returntype == "var" || returntype == "blop::var") &&
(arglist == "var,var" || arglist == "blop::var,blop::var"))
{
f = new var_func_var_var;
}
else if((returntype == "var" || returntype == "blop::var") &&
(arglist == "var,var,var" || arglist == "blop::var,blop::var,blop::var"))
{
f = new var_func_var_var_var;
}
else if((returntype == "var" || returntype == "blop::var") &&
(arglist == "var,var,var,var" || arglist == "blop::var,blop::var,blop::var,blop::var"))
{
f = new var_func_var_var_var_var;
}
else if( (returntype == "double") &&
(
arglist == "const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&" ||
arglist == "const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&"
)
)
{
f = new double_func_aref_aref_aref_aref_aref;
}
else if( (returntype == "double") &&
(
arglist == "const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&" ||
arglist == "const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&"
)
)
{
f = new double_func_aref_aref_aref_aref_aref_aref;
}
else if( (returntype == "double") &&
(
arglist == "const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&,"
"const std::vector<blop::var>&" ||
arglist == "const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&,"
"const vector<blop::var>&"
)
)
{
f = new double_func_aref_aref_aref_aref_aref_aref_aref;
}
else if((returntype == "complex" ||
returntype == "complex<double>" ||
returntype == "std::complex<double>")
&& arglist == "double")
{
f = new complex_func_double;
}
else if(returntype == "void" && arglist == "double*,double*")
{
f = new void_func_doublep_doublep;
}
if(f != 0)
{
f->functype_ = functype;
f->ptr_ = methods[i].PointerToFunc();
f->fname_ = function_name_global;
f->arglist_ = arglist;
break;
}
}
return f;
}
}