diff options
-rw-r--r-- | sci_gateway/cpp/sci_octave.cpp | 76 | ||||
-rw-r--r-- | src/fun.cpp | 19 | ||||
-rw-r--r-- | src/fun.h | 98 |
3 files changed, 128 insertions, 65 deletions
diff --git a/sci_gateway/cpp/sci_octave.cpp b/sci_gateway/cpp/sci_octave.cpp index 1ccda51..80b658b 100644 --- a/sci_gateway/cpp/sci_octave.cpp +++ b/sci_gateway/cpp/sci_octave.cpp @@ -29,28 +29,39 @@ extern "C" #include <stdlib.h> static const char fname[] = "octave_fun"; - - /*! \brief Function to connect to Scilab's API. - * - * This function will get Data from Scilab, proccess the data - * in Octave then return the output back to Scilab using the - * API. - */ + + /** + * @brief Function to connect to Scilab's API. + * + * This function will get Data from Scilab, proccess the data + * in Octave then return the output back to Scilab using the + * API. + * + * @param env Scialb env + * @param nin[in] Number of input arguments + * @param in[in] Input Parameters + * @param nopt[in] Number of optional parameters + * @param opt[in] Optional parameters + * @param nout[out] Number of expected output parametets + * @param out[out] Array for output data + * @return int + */ int sci_octave_fun(scilabEnv env, int nin, scilabVar *in, int nopt, scilabOpt *opt, int nout, scilabVar *out) { - //printf("nin: %d\n", nin); + //DEBUG//printf("nin: %d\n", nin); + // Check number of inputs if (nin < 1) { Scierror(999, _("%s: Wrong number of input arguments. Atleast %d expected.\n"), fname, 2); return STATUS_ERROR; } + // Declare and initialize the API variables FUNCCALL funcall; FUNCCALL *funptr = &funcall; funcall.n_in_arguments = nin; funcall.n_out_user = nout; - FUNCARGS ins[funcall.n_in_arguments * nout]; FUNCARGS *argptr = ins; @@ -67,14 +78,20 @@ extern "C" double *in_real; double *in_img; + + + // Check the data type of input variables and format them into the FUNNCALL for (i = 0; i < nin; i++) { + // Check if [in] of type Sci:matrix if (scilab_getType(env, in[i]) == 1) { ins[i].type = TYPE_DOUBLE; + + // Check if [in] is of type Sci:complex if (scilab_isComplex(env, in[i]) == 1) { - //printf("input %d is complex \n", i); + //DEBUG//printf("input %d is complex \n", i); ins[i].is_in_cmplx = 1; size = scilab_getDim2d(env, in[i], &row, &col); ins[i].n_in_rows = row; @@ -100,9 +117,10 @@ extern "C" } } } + // [in] is not of type Sci:complex else { - //printf("input %d is NOT complex \n", i); + //DEBUG//printf("input %d is NOT complex \n", i); ins[i].is_in_cmplx = 0; size = scilab_getDim2d(env, in[i], &row, &col); ins[i].n_in_rows = row; @@ -112,7 +130,7 @@ extern "C" ins[i].in_data_real = malloc(sizeof(double) * size); d = (double *)ins[i].in_data_real; - ////This code snippet is to flatten matrix row wise and then store it + //DEBUG//This code snippet is to flatten matrix row wise and then store it int p, q, k = 0; for (p = 0; p < row; p++) { @@ -126,6 +144,7 @@ extern "C" } ///////////////////////////////////////// } + // Check if [in] of type SCI:Matrix of strings else if (scilab_getType(env, in[i]) == 10) { ins[i].is_in_cmplx = 0; @@ -276,7 +295,7 @@ extern "C" if (!err.empty() && status_fun == 0) sciprint("Warning from Octave\n%s", err.c_str()); buffer_err.str(""); - + //printf("in scilab status_fun is: %d\n", status_fun); //printf("in scilab funcall.n_out_arguments is: %d\n", funcall.n_out_arguments); //printf("in scilab funcall.n_out_user is: %d\n", funcall.n_out_user); @@ -289,10 +308,12 @@ extern "C" Scierror(999, "Error from Octave\n%s", err.c_str()); return 1; } + // Format output variable for SciLab else if (funcall.n_out_user <= funcall.n_out_arguments) { for (i = 0; i < nout; i++) { + // Format Complex data type if (ins[i].is_out_cmplx == 1) { //printf("output %d is complex\n", i); @@ -314,20 +335,24 @@ extern "C" out_img[j] = ocd[j]; } } - else if (ins[i].is_out_struct == 1){ + // Format Struct data type + else if (ins[i].is_out_struct == 1) + { // creating scilab struct out[i] = scilab_createStruct(env); int structLen = ins[i].n_out_struct_len; - - FUNCSTRUCT* outStruct = ins[i].out_struct; - for (int j = 0; j < structLen; j++){ + FUNCSTRUCT *outStruct = ins[i].out_struct; + + for (int j = 0; j < structLen; j++) + { // std::printf("currKey in sciOctave.cpp OP: %ls\n", outStruct[j].key); - scilab_addField(env, out[i], (const wchar_t*) outStruct[j].key); + scilab_addField(env, out[i], (const wchar_t *)outStruct[j].key); scilabVar currValue = NULL; - if (outStruct[j].type == TYPE_COMPLEX){ + if (outStruct[j].type == TYPE_COMPLEX) + { currValue = scilab_createDoubleMatrix2d(env, outStruct[j].rows, outStruct[j].cols, 1); - + double *outReal = NULL; double *outImg = NULL; scilab_getDoubleComplexArray(env, currValue, &outReal, &outImg); @@ -391,11 +416,16 @@ extern "C" Scierror(77, _("%s: Wrong number of output arguments: This function can return a maximum of %d output(s).\n"), fname, funcall.n_out_arguments); return 1; } + + // Free the mem allocated for out variables for (i = 0; i < nout; i++) { - if (ins[i].is_out_struct == 1){ - FUNCSTRUCT* tempStruct = ins[i].out_struct; - for (int j = 0; j < ins[i].n_out_struct_len; j++){ + // + if (ins[i].is_out_struct == 1) + { + FUNCSTRUCT *tempStruct = ins[i].out_struct; + for (int j = 0; j < ins[i].n_out_struct_len; j++) + { // std::wstring tempWStr((wchar_t *) tempStruct[j].key); // std::string(tempWStr.begin(), tempWStr.end()); // std::cout << "freeing key: " << std::string(tempWStr.begin(), tempWStr.end()) << std::endl; diff --git a/src/fun.cpp b/src/fun.cpp index 1362e67..ab2afca 100644 --- a/src/fun.cpp +++ b/src/fun.cpp @@ -30,9 +30,9 @@ extern "C" int fun(FUNCARGS *inp, FUNCCALL *funcall)
{
- static octave::interpreter interpreter;
+ static octave::interpreter interpreter;
bool status = interpreter.initialized();
-
+ // Check octave interpreter loaded
if (status == false)
{
interpreter.initialize();
@@ -55,8 +55,10 @@ extern "C" char str_pkg[20];
int pkg = 0;
int nouts;
+ // Format the input data values into data type acceptable by Octave
for (l = 0; l < funcall->n_in_arguments; l++)
{
+ //check if Input type is Double
if (inp[l].type == TYPE_DOUBLE)
{
if (inp[l].is_in_cmplx == 1)
@@ -92,6 +94,7 @@ extern "C" in(l - str_count) = inMatrix_x;
}
}
+ //check if Input type is string
else if (inp[l].type == TYPE_STRING)
{
//std::cout << "In fun string. l is : " << l << '\n';
@@ -113,6 +116,7 @@ extern "C" //std::cout << "String is: " << c << '\n';
}
+ //check if Input type is struct
else if (inp[l].type == TYPE_STRUCT){
FUNCSTRUCT* inStruct = inp[l].in_struct;
@@ -177,17 +181,18 @@ extern "C" //std::cout << "loading package " << str_pkg << '\n';
octave::feval("pkg", ovl("load", str_pkg), 0);
}
-
+ // Use feval to compute the required values
octave_value_list out = octave::feval(str_fun, in, funcall->n_out_user);
int row = 0;
int col = 0;
nouts = out.length();
funcall->n_out_arguments = nouts;
- // std::cout << "funcall->n_out_arguments is: " << funcall->n_out_arguments << '\n';
-
+ // DEBUG // std::cout << "funcall->n_out_arguments is: " << funcall->n_out_arguments << '\n';
+ // Format and set the output data values from Octave into the FUNCARGS
for (unsigned int ii = 0; ii < nouts; ii++)
{
+ //Format complex data
if (out(ii).iscomplex() == 1)
{
inp[ii].is_out_cmplx = 1;
@@ -216,6 +221,7 @@ extern "C" }
}
}
+ //Format Struct data
else if(out(ii).isstruct()){
inp[ii].is_out_struct = 1;
@@ -335,6 +341,7 @@ extern "C" }
}
}
+ // Exception handling Octave
catch (const octave::exit_exception &ex)
{
std::cerr << "Octave interpreter exited with status = "
@@ -343,7 +350,7 @@ extern "C" }
catch (const octave::execution_exception &)
{
- //std::cerr << "error encountered in Octave evaluator!" << std::endl;
+ //DEBUG//std::cerr << "error encountered in Octave evaluator!" << std::endl;
return 1;
}
return 0;
@@ -13,53 +13,79 @@ //extern "C" int fun (double* answ, double* in1, int in1_row, std::string name, std::string opt); extern "C" -{ +{ + /** + * + * @brief Enumeration for the data types suported by the fun() + * + */ typedef enum { - TYPE_DOUBLE, - TYPE_COMPLEX, - TYPE_STRING, - TYPE_STRUCT, + TYPE_DOUBLE, /**similar to scilab double*/ + TYPE_COMPLEX, /**similar to scilab complex*/ + TYPE_STRING, /**similar to scilab string*/ + TYPE_STRUCT, /**similar to scilab struct*/ }FUNCTYPE; + /** + * @struct FUNCSTRUCT + * @brief Struct used to pass structs to Octave from the fun library + * @var type + * + */ + typedef struct { - FUNCTYPE type; // type of value in struct's field - void* key; // key of struct field - int rows; // rows dimension of struct field's value - int cols; // cols dimension of struct fields' value - void* dataReal; // Real data if struct field's value is real - void* dataImg; // Img data if struct field's value is complex - void* str; // string data if struct field's value is string + FUNCTYPE type; /// Type of value in struct's field + void* key; /// key of struct field + int rows; /// rows dimension of struct field's value + int cols; /// cols dimension of struct fields' value + void* dataReal; /// Real data if struct field's value is real + void* dataImg; /// Img data if struct field's value is complex + void* str; /// String data if struct field's value is string } FUNCSTRUCT; + /** + * @brief Struct used to send/receive Scilab data to/from the gateway to fun.cpp API + * + */ + typedef struct { - FUNCTYPE type; - int n_in_rows; - int n_in_cols; - int n_in_struct_len; // ip struct length - int n_out_rows; - int n_out_cols; - int n_out_struct_len; // op struct length - int is_in_cmplx; - int is_out_cmplx; - int is_out_string; - int is_out_struct; - void* in_data_real; - void* in_data_img; - void* out_data_real; - void* out_data_img; - FUNCSTRUCT* in_struct; - FUNCSTRUCT* out_struct; + FUNCTYPE type; /// Type of data + int n_in_rows; /// Input rows dimension of data + int n_in_cols; /// Input cols dimension of data + int n_in_struct_len; /// input struct length + int n_out_rows; /// Ouput rows dimension of data + int n_out_cols; /// Output cold dimension of data + int n_out_struct_len; /// Output struct length + int is_in_cmplx; /// Input is a Complex data type + int is_out_cmplx; /// Output is a Complex data type + int is_out_struct; /// Output is a Struct data type + void* in_data_real; /// Input real part (complex) array + void* in_data_img; /// Input imaginary part (complex) array + void* out_data_real; /// Output real part (complex) array + void* out_data_img; /// Output imaginary part (complex) array + FUNCSTRUCT* in_struct; /// Input struct + FUNCSTRUCT* out_struct; /// Output struct } FUNCARGS; - + /** + * @brief Struct used to call and pass the data to fun.cpp API + * + */ typedef struct { - int n_in_arguments; // number of input arguments - int n_out_arguments; // number of output arguments - int n_out_user; // number of output arguments - char *err; // Name + int n_in_arguments; /// Number of input arguments + int n_out_arguments; /// Number of output arguments + int n_out_user; /// Number of output arguments + char *err; /// Return errors //char *package; //Name of octave package to be loaded - FUNCARGS *argument; + FUNCARGS *argument; /// Struct defining and containing the data } FUNCCALL; - + /** + * @brief API Function to call/receive and pass the data to fun API + * + * + * @param arr Input data FUNCARGS + * @param call Input Arguments FUNCCALL + * @return int + */ int fun(FUNCARGS *arr, FUNCCALL *call); } |