diff options
author | KRIXUS-alpha | 2021-05-12 14:04:10 +0530 |
---|---|---|
committer | KRIXUS-alpha | 2021-05-12 14:04:10 +0530 |
commit | d5d77fe4d8f3cd14dc3083ae0e5687b4f56976e4 (patch) | |
tree | 534cf98d5b3313eaabca52de75e5ad4fb395f4dd | |
parent | 540c02f594fe49e47828a589115f282f95304b72 (diff) | |
download | fossee-scilab-octave-toolbox-d5d77fe4d8f3cd14dc3083ae0e5687b4f56976e4.tar.gz fossee-scilab-octave-toolbox-d5d77fe4d8f3cd14dc3083ae0e5687b4f56976e4.tar.bz2 fossee-scilab-octave-toolbox-d5d77fe4d8f3cd14dc3083ae0e5687b4f56976e4.zip |
documentation struct
-rw-r--r-- | sci_gateway/cpp/sci_octave.cpp | 618 | ||||
-rw-r--r-- | src/fun.cpp | 309 | ||||
-rw-r--r-- | src/fun.h | 96 |
3 files changed, 734 insertions, 289 deletions
diff --git a/sci_gateway/cpp/sci_octave.cpp b/sci_gateway/cpp/sci_octave.cpp index 5f1f685..f106be3 100644 --- a/sci_gateway/cpp/sci_octave.cpp +++ b/sci_gateway/cpp/sci_octave.cpp @@ -17,9 +17,9 @@ extern "C" { -#include<Scierror.h> -#include<sciprint.h> -#include<api_scilab.h> +#include <Scierror.h> +#include <sciprint.h> +#include <api_scilab.h> #include "localization.h" #include "fun.h" #include <cstdio> @@ -28,226 +28,472 @@ extern "C" #include "os_string.h" #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. + * + * @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) - -static const char fname[] = "octave_fun"; -int sci_octave_fun(scilabEnv env, int nin, scilabVar* in, int nopt, scilabOpt* opt, int nout, scilabVar* out) - -{ -//printf("nin: %d\n", nin); - if (nin < 2) - { - Scierror(999, _("%s: Wrong number of input arguments. Atleast %d expected.\n"), fname, 2); - return STATUS_ERROR; - } - - 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; - - int i,j; - double* d; - double* rd = NULL;; - double* cd = NULL;; - int size; - char str[20]; - char* c; - double* n = NULL; - int row = 0; - int col = 0; - double* in_real; - double* in_img; - - for(i=0;i<nin;i++) { - if(scilab_getType(env, in[i])==1) - { - ins[i].type = TYPE_DOUBLE; - if(scilab_isComplex(env, in[i])==1) + //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; + + int i, j; + double *d; + double *rd = NULL; + double *cd = NULL; + int size; + char str[20]; + char *c; + double *n = NULL; + int row = 0; + int col = 0; + 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) { - //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; - ins[i].n_in_cols = col; - scilab_getDoubleComplexArray(env, in[i],&in_real, &in_img); - - ins[i].in_data_real = malloc(sizeof(double)*size); - ins[i].in_data_img = malloc(sizeof(double)*size); - rd = (double *)ins[i].in_data_real; - cd = (double *)ins[i].in_data_img; - - ////This code snippet is to flatten matrix row wise and then store it - int p,q,k = 0; - for(p=0;p<row;p++) + ins[i].type = TYPE_DOUBLE; + + // Check if [in] is of type Sci:complex + if (scilab_isComplex(env, in[i]) == 1) { - for(q=0;q<col;q++) + //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; + ins[i].n_in_cols = col; + scilab_getDoubleComplexArray(env, in[i], &in_real, &in_img); + + ins[i].in_data_real = malloc(sizeof(double) * size); + ins[i].in_data_img = malloc(sizeof(double) * size); + rd = (double *)ins[i].in_data_real; + cd = (double *)ins[i].in_data_img; + + ////This code snippet is to flatten matrix row wise and then store it + int p, q, k = 0; + for (p = 0; p < row; p++) { - rd[k] = in_real[p + q*row]; - cd[k] = in_img[p + q*row]; - k++; - //printf("%d\n",in_real[k]); - //printf("%d\n",in_img[k]); + for (q = 0; q < col; q++) + { + rd[k] = in_real[p + q * row]; + cd[k] = in_img[p + q * row]; + k++; + //printf("%d\n",in_real[k]); + //printf("%d\n",in_img[k]); + } } } - } - else - { - //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; - ins[i].n_in_cols = col; - scilab_getDoubleArray(env, in[i], &n); - - 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 - int p,q,k = 0; - for(p=0;p<row;p++) + // [in] is not of type Sci:complex + else { - for(q=0;q<col;q++) + //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; + ins[i].n_in_cols = col; + scilab_getDoubleArray(env, in[i], &n); + + ins[i].in_data_real = malloc(sizeof(double) * size); + d = (double *)ins[i].in_data_real; + + //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++) { - d[k] = n[p + q*row]; - k++; - //printf("%f\n",d[j]); + for (q = 0; q < col; q++) + { + d[k] = n[p + q * row]; + k++; + //printf("%f\n",d[j]); + } } } } -///////////////////////////////////////// - } - else if(scilab_getType(env, in[i])==10) - { - ins[i].is_in_cmplx=0; - wchar_t* in1 = 0; + // Check if [in] of type SCI:Matrix of strings + else if (scilab_getType(env, in[i]) == 10) + { + ins[i].is_in_cmplx = 0; + wchar_t *in1 = 0; - scilab_getString(env, in[i], &in1); - //printf("%S\n", in1); + scilab_getString(env, in[i], &in1); + //printf("%S\n", in1); - wcstombs(str, in1, sizeof(str)); - //printf("%s\n", str); - if(str) + wcstombs(str, in1, sizeof(str)); + //printf("%s\n", str); + if (str) + { + //printf("lenght of string input: %d\n", strlen(str)); + ins[i].type = TYPE_STRING; + ins[i].n_in_rows = 1; + ins[i].n_in_cols = strlen(str); + size = (ins[i].n_in_rows) * (ins[i].n_in_cols); + ins[i].in_data_real = malloc(sizeof(char) * (size + 1)); + c = (char *)ins[i].in_data_real; + int ci; + + strcpy(c, str); + ins[i].n_in_cols = strlen(c); + //printf("in scilab strin is: %s\n", c); + } + } + // Check if [in] of type Sci:struct + else if (scilab_getType(env, in[i]) == 18) { - //printf("lenght of string input: %d\n", strlen(str)); - ins[i].type = TYPE_STRING; - ins[i].n_in_rows = 1; - ins[i].n_in_cols = strlen(str); - size = (ins[i].n_in_rows)*(ins[i].n_in_cols); - ins[i].in_data_real = malloc(sizeof(char)*size+1); - c = (char *)ins[i].in_data_real; - int ci; - - strcpy(c,str); - ins[i].n_in_cols = strlen(c); - //printf("in scilab strin is: %s\n", c); + ins[i].type = TYPE_STRUCT; + wchar_t **keys = NULL; + scilabVar struct_out; + int dims = 0; + + dims = scilab_getFields(env, in[i], &keys); // Retrieving Struct Keys + ins[i].n_in_struct_len = dims; + //std::cout<<dims<<std::endl; + + // allocating memory for keys and values + ins[i].in_struct = (FUNCSTRUCT *)malloc(sizeof(FUNCSTRUCT) * dims); + FUNCSTRUCT *inStruct = ins[i].in_struct; + + for (j = 0; j < dims; j++) + { + // storing the key + inStruct[j].key = malloc(sizeof(keys[j]) + 1); + wcpcpy((wchar_t *)inStruct[j].key, keys[j]); + + struct_out = scilab_getStructMatrix2dData(env, in[i], keys[j], 0, 0); // Retrieving Curr Value + + // Checking Type of value in struct + if (scilab_getType(env, struct_out) == 1) + { + // Double Value + if (scilab_isComplex(env, struct_out) == 1) + { + // Complex Value + //printf("input %d is complex \n", i) + inStruct[j].type = TYPE_COMPLEX; + size = scilab_getDim2d(env, struct_out, &row, &col); + inStruct[j].rows = row; + inStruct[j].cols = col; + scilab_getDoubleComplexArray(env, struct_out, &in_real, &in_img); + + inStruct[j].dataReal = malloc(sizeof(double) * size); + inStruct[j].dataImg = malloc(sizeof(double) * size); + rd = (double *)inStruct[j].dataReal; + cd = (double *)inStruct[j].dataImg; + + ////This code snippet is to flatten matrix row wise and then store it + int p, q, k = 0; + for (p = 0; p < row; p++) + { + for (q = 0; q < col; q++) + { + // printf("%d\n",in_real[p + q * row]); + // printf("%d\n",in_img[p + q * row]); + rd[k] = in_real[p + q * row]; + cd[k] = in_img[p + q * row]; + k++; + } + } + } + else + { + // Real Values Only + inStruct[j].type = TYPE_DOUBLE; + //printf("input %d is NOT complex \n", i); + size = scilab_getDim2d(env, struct_out, &row, &col); + scilab_getDoubleArray(env, struct_out, &n); + + inStruct[j].rows = row; + inStruct[j].cols = col; + + inStruct[j].dataReal = malloc(sizeof(double) * size); + d = (double *)inStruct[j].dataReal; + + ////This code snippet is to flatten matrix row wise and then store it + int p, q, k = 0; + for (p = 0; p < row; p++) + { + for (q = 0; q < col; q++) + { + // printf("%f\n",n[k]); + d[k] = n[k]; + k++; + } + } + } + } + else if (scilab_getType(env, struct_out) == 10) + { + inStruct[j].type = TYPE_STRING; + wchar_t *in1 = NULL; + scilab_getString(env, struct_out, &in1); + //printf("%S\n", in1); + + inStruct[j].str = malloc(sizeof(wchar_t) * (wcslen(in1) + 1)); + wcpcpy((wchar_t *)inStruct[j].str, in1); + // printf("%s\n", str); + } + else + { + Scierror(999, _("%s: Wrong type of input argument %d.\n"), fname, i); + return STATUS_ERROR; + } + } + } + else + { + Scierror(999, _("%s: Wrong type of input argument %d.\n"), fname, i); + return STATUS_ERROR; } } - else - { - Scierror(999, _("%s: Wrong type of input argument %d.\n"), fname, i); - return STATUS_ERROR; - } - } - - // Capturing Errors and warnings - std::stringstream buffer_err; - // set our error buffer - std::cerr.rdbuf(buffer_err.rdbuf()); + // Capturing Errors and warnings + std::stringstream buffer_err; - int status_fun = fun(argptr, funptr); + // set our error buffer + std::cerr.rdbuf(buffer_err.rdbuf()); - // grab error buffer contents - std::string err = buffer_err.str(); + // call the fun() function + int status_fun = fun(argptr, funptr); - 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); -//printf("in scilab ins[0].n_out_rows is: %d\n", ins[0].n_out_rows); -//printf("in scilab ins[0].n_out_cols is: %d\n", ins[0].n_out_cols); + // grab error buffer contents + std::string err = buffer_err.str(); + if (!err.empty() && status_fun == 0) + sciprint("Warning from Octave\n%s", err.c_str()); + buffer_err.str(""); -//printf("in scilab ouput args are: %d\n", funcall.n_out_arguments); - if(status_fun==1) - { - Scierror(999,"Error from Octave\n%s", err.c_str()); - return 1; - } - else if(funcall.n_out_user <= funcall.n_out_arguments) - { - for(i=0;i<nout;i++) - { - - if(ins[i].is_out_cmplx==1) + //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); + //printf("in scilab ins[0].n_out_rows is: %d\n", ins[0].n_out_rows); + //printf("in scilab ins[0].n_out_cols is: %d\n", ins[0].n_out_cols); + //printf("in scilab ouput args are: %d\n", funcall.n_out_arguments); + + if (status_fun == 1) { - //printf("output %d is complex\n", i); - out[i] = scilab_createDoubleMatrix2d(env, ins[i].n_out_rows, ins[i].n_out_cols, 1); - double* out_real = NULL; - double* out_img = NULL; - scilab_getDoubleComplexArray(env, out[i],&out_real, &out_img); - int len = ins[i].n_out_rows*ins[i].n_out_cols; - double* ord = (double *)ins[i].out_data_real; - double* ocd = (double *)ins[i].out_data_img; - //printf("output length is: %d\n", len); - for(j=0; j<len; j++) + 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) { - out_real[j] = ord[j]; + //printf("output %d is complex\n", i); + out[i] = scilab_createDoubleMatrix2d(env, ins[i].n_out_rows, ins[i].n_out_cols, 1); + double *out_real = NULL; + double *out_img = NULL; + scilab_getDoubleComplexArray(env, out[i], &out_real, &out_img); + int len = ins[i].n_out_rows * ins[i].n_out_cols; + double *ord = (double *)ins[i].out_data_real; + double *ocd = (double *)ins[i].out_data_img; + //printf("output length is: %d\n", len); + for (j = 0; j < len; j++) + { + out_real[j] = ord[j]; + } + + for (j = 0; j < len; j++) + { + out_img[j] = ocd[j]; + } } + // 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(j=0; j<len; j++) + 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); + scilabVar currValue = NULL; + 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); + + double *dReal = (double *)outStruct[j].dataReal; + double *dImg = (double *)outStruct[j].dataImg; + + int size = outStruct[j].rows * outStruct[j].cols; + for (int k = 0; k < size; k++) + { + outReal[k] = dReal[k]; + } + for (int k = 0; k < size; k++) + { + outImg[k] = dImg[k]; + } + + // set the key-value pair in scilab struct + scilab_setStructMatrix2dData(env, out[i], (const wchar_t *)outStruct[j].key, 0, 0, currValue); + } + else if (outStruct[j].type == TYPE_DOUBLE) + { + currValue = scilab_createDoubleMatrix2d(env, outStruct[j].rows, outStruct[j].cols, 1); + + double *outReal = NULL; + scilab_getDoubleArray(env, currValue, &outReal); + + double *dReal = (double *)outStruct[j].dataReal; + + int size = outStruct[j].rows * outStruct[j].cols; + for (int k = 0; k < size; k++) + { + outReal[k] = dReal[k]; + } + + // set the key-value pair in scilab struct + scilab_setStructMatrix2dData(env, out[i], (const wchar_t *)outStruct[j].key, 0, 0, currValue); + } + else if (outStruct[j].type == TYPE_STRING) + { + scilab_setStructMatrix2dData(env, out[i], (const wchar_t *)outStruct[j].key, 0, 0, scilab_createString(env, (const wchar_t *)outStruct[j].str)); + } + } + } + // Format Double data type + else { - out_img[j] = ocd[j]; + //printf("output %d is NOT complex\n", i); + out[i] = scilab_createDoubleMatrix2d(env, ins[i].n_out_rows, ins[i].n_out_cols, 0); + double *out1 = NULL; + scilab_getDoubleArray(env, out[i], &out1); + int len = ins[i].n_out_rows * ins[i].n_out_cols; + double *dd = (double *)ins[i].out_data_real; + //printf("output length is: %d\n", len); + for (j = 0; j < len; j++) + { + out1[j] = dd[j]; //.float_value(); + } } + } } else { - //printf("output %d is NOT complex\n", i); - out[i] = scilab_createDoubleMatrix2d(env, ins[i].n_out_rows, ins[i].n_out_cols, 0); - double* out1 = NULL; - scilab_getDoubleArray(env, out[i], &out1); - int len = ins[i].n_out_rows*ins[i].n_out_cols; - double* dd = (double *)ins[i].out_data_real; - //printf("output length is: %d\n", len); - for(j=0; j<len; j++) + 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++) { - out1[j] = dd[j];//.float_value(); + // 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; + free(tempStruct[j].key); + if (tempStruct[j].type == TYPE_STRING) + { + free(tempStruct[j].str); + } + if (tempStruct[j].type == TYPE_DOUBLE) + { + free(tempStruct[j].dataReal); + } + if (tempStruct[j].type == TYPE_COMPLEX) + { + free(tempStruct[j].dataReal); + free(tempStruct[j].dataImg); + } } + free(ins[i].out_struct); + } + else + { + free(ins[i].out_data_real); } - } - } - else - { - 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; - } - - - - - for(i=0;i<nout;i++) - { - free(ins[i].out_data_real); - - if(ins[i].is_out_cmplx==1) - free(ins[i].out_data_img); - } - for(i=0;i<nin;i++) - { - free(ins[i].in_data_real); + if (ins[i].is_out_cmplx == 1) + { + free(ins[i].out_data_img); + } + } + // Free the mem allocated for in variables + for (i = 0; i < nin; i++) + { + if (ins[i].type == TYPE_STRUCT) + { + FUNCSTRUCT *tempStruct = ins[i].in_struct; + for (int j = 0; j < ins[i].n_in_struct_len; j++) + { + free(tempStruct[j].key); + if (tempStruct[j].type == TYPE_STRING) + { + free(tempStruct[j].str); + } + if (tempStruct[j].type == TYPE_DOUBLE) + { + free(tempStruct[j].dataReal); + } + if (tempStruct[j].type == TYPE_COMPLEX) + { + free(tempStruct[j].dataReal); + free(tempStruct[j].dataImg); + } + } + free(ins[i].in_struct); + } + else + { + free(ins[i].in_data_real); + } - if(ins[i].is_in_cmplx==1) - free(ins[i].in_data_img); + if (ins[i].is_in_cmplx == 1) + { + free(ins[i].in_data_img); + } + } + return 0; } - return 0; -} } diff --git a/src/fun.cpp b/src/fun.cpp index 4eeb24c..71b7d45 100644 --- a/src/fun.cpp +++ b/src/fun.cpp @@ -17,116 +17,183 @@ #include <octave/interpreter.h>
#include <math.h>
#include <string>
+#include <cstring>
#include "fun.h"
extern "C"
{
+ /*!
+ * \brief Function to Interact with Octave's API.
+ *
+ * This Function will be communicating with Octave to access it's function.
+ */
int fun(FUNCARGS *inp, FUNCCALL *funcall)
{
- static octave::interpreter interpreter;
+ static octave::interpreter interpreter;
bool status = interpreter.initialized();
-
- if(status==false)
+ // Check octave interpreter loaded
+ if (status == false)
{
- interpreter.initialize ();
- int status_exec = interpreter.execute ();
+ interpreter.initialize();
+ int status_exec = interpreter.execute();
if (status_exec != 0)
{
std::cerr << "creating embedded Octave interpreter failed!"
- << std::endl;
+ << std::endl;
}
}
-
+
try
- {
+ {
octave_value_list in;
unsigned int k;
int l;
int str_count = 0;
char str_fun[20];
char str_pkg[20];
- int pkg=0;
+ int pkg = 0;
int nouts;
- for(l=0;l<funcall->n_in_arguments;l++)
+ // Format the input data values into data type acceptable by Octave
+ for (l = 0; l < funcall->n_in_arguments; l++)
{
- if(inp[l].type==TYPE_DOUBLE)
+ //check if Input type is Double
+ if (inp[l].type == TYPE_DOUBLE)
{
- if(inp[l].is_in_cmplx==1)
+ if (inp[l].is_in_cmplx == 1)
{
- ComplexMatrix matr = ComplexMatrix (inp[l].n_in_rows,inp[l].n_in_cols);
- double* id_real = (double *)inp[l].in_data_real;
- double* id_img = (double *)inp[l].in_data_img;
- k=0;
- for (int r=0;r<inp[l].n_in_rows;r++)
- {
- for(int c=0;c<inp[l].n_in_cols;c++)
- {
- Complex cc(id_real[k],id_img[k]);
- matr(r,c) = cc;
+ ComplexMatrix matr = ComplexMatrix(inp[l].n_in_rows, inp[l].n_in_cols);
+ double *id_real = (double *)inp[l].in_data_real;
+ double *id_img = (double *)inp[l].in_data_img;
+ k = 0;
+ for (int r = 0; r < inp[l].n_in_rows; r++)
+ {
+ for (int c = 0; c < inp[l].n_in_cols; c++)
+ {
+ Complex cc(id_real[k], id_img[k]);
+ matr(r, c) = cc;
k++;
- }
- }
- in(l-str_count) = octave_value(matr);
+ }
+ }
+ in(l - str_count) = octave_value(matr);
}
else
{
- Matrix inMatrix_x(inp[l].n_in_rows,inp[l].n_in_cols);
- double* id = (double *)inp[l].in_data_real;
- k=0;
- for( unsigned int i = 0; i < inp[l].n_in_rows; i++ )
+ Matrix inMatrix_x(inp[l].n_in_rows, inp[l].n_in_cols);
+ double *id = (double *)inp[l].in_data_real;
+ k = 0;
+ for (unsigned int i = 0; i < inp[l].n_in_rows; i++)
{
- for( unsigned int j = 0; j < inp[l].n_in_cols; j++ )
+ for (unsigned int j = 0; j < inp[l].n_in_cols; j++)
{
- inMatrix_x(i, j) = id[k];
- k++;
+ inMatrix_x(i, j) = id[k];
+ k++;
}
}
- in(l-str_count) = inMatrix_x;
+ in(l - str_count) = inMatrix_x;
}
}
- else if(inp[l].type==TYPE_STRING)
+ //check if Input type is string
+ else if (inp[l].type == TYPE_STRING)
{
//std::cout << "In fun string. l is : " << l << '\n';
-
- char* c = (char *)inp[l].in_data_real;
+
+ char *c = (char *)inp[l].in_data_real;
//std::cout << "String is: " << c << '\n';
- if(l==0)
- strcpy(str_fun,c);
- else if(l==1)
+ if (l == 0)
+ strcpy(str_fun, c);
+ else if (l == 1)
{
- strcpy(str_pkg,c);
- pkg=1;
- }
+ strcpy(str_pkg, c);
+ pkg = 1;
+ }
else
- in(l-str_count) = c;
+ in(l - str_count) = c;
str_count++;
//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;
+
+ octave_scalar_map inOctaveStruct;
+
+ // populate the octave structure
+ for (int j = 0; j < inp[l].n_in_struct_len; j++){
+ std::string currKey;
+ octave_value currValue;
- if(pkg==1)
+ // converting wchar_t* to string for octave
+ std::wstring currKeyWStr((wchar_t *) inStruct[j].key);
+ currKey = std::string(currKeyWStr.begin(), currKeyWStr.end());
+
+
+ // get Value
+ if (inStruct[j].type == TYPE_COMPLEX){
+ ComplexMatrix currValueMatrix = ComplexMatrix(inStruct[j].rows, inStruct[j].cols);
+ double* dReal = (double *)inStruct[j].dataReal;
+ double* dImg = (double *)inStruct[j].dataImg;
+ k = 0;
+ for (int r = 0; r < inStruct[j].rows; r++)
+ {
+ for (int c = 0; c < inStruct[j].cols; c++)
+ {
+ Complex currItem(dReal[k], dImg[k]);
+ currValueMatrix(r, c) = currItem;
+ k++;
+ }
+ }
+ currValue = currValueMatrix;
+ }
+ else if(inStruct[j].type == TYPE_DOUBLE){
+ Matrix currValueMatrix = Matrix(inStruct[j].rows, inStruct[j].cols);
+ double* dReal = (double *)inStruct[j].dataReal;
+ k = 0;
+ for (int r = 0; r < inStruct[j].rows; r++)
+ {
+ for (int c = 0; c < inStruct[j].cols; c++)
+ {
+ currValueMatrix(r, c) = dReal[k];
+ k++;
+ }
+ }
+ currValue = currValueMatrix;
+ }
+ else if (inStruct[j].type == TYPE_STRING){
+ std::wstring currValueWStr((wchar_t *) inStruct[j].str);
+ std::string currValueStr(currValueWStr.begin(), currValueWStr.end());
+ currValue = octave_value(currValueStr);
+ }
+ inOctaveStruct.assign(currKey, currValue);
+ }
+
+ // insert struct to input octave list
+ in(l - str_count) = inOctaveStruct;
+ }
+ }
+ // Load the octave package
+ if (pkg == 1)
{
//std::cout << "loading package " << str_pkg << '\n';
- octave::feval ("pkg", ovl ("load", str_pkg), 0);
+ 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);
- octave_value_list out = octave::feval (str_fun, in, funcall->n_out_user);
-
-
- int row;
- int col;
+ 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';
-
- for( unsigned int ii = 0; ii < nouts; ii++ )
+ // 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++)
{
- if(out(ii).iscomplex()==1)
+ //Format complex data
+ if (out(ii).iscomplex() == 1)
{
- inp[ii].is_out_cmplx=1;
+ inp[ii].is_out_cmplx = 1;
//std::cout << "out "<< ii<< " is complex" << '\n';
ComplexMatrix cmOut(out(ii).complex_matrix_value());
//std::cout << "cmOut "<< cmOut << '\n';
@@ -136,54 +203,144 @@ extern "C" col = cmOut.columns();
inp[ii].n_out_rows = row;
inp[ii].n_out_cols = col;
- k=0;
- inp[ii].out_data_real = malloc(sizeof(double)*(row*col));
- inp[ii].out_data_img = malloc(sizeof(double)*(row*col));
- double* rd = (double *)inp[ii].out_data_real;
- double* cd = (double *)inp[ii].out_data_img;
- for(unsigned int i=0;i<row;i++)
+ k = 0;
+ inp[ii].out_data_real = malloc(sizeof(double) * (row * col));
+ inp[ii].out_data_img = malloc(sizeof(double) * (row * col));
+ double *rd = (double *)inp[ii].out_data_real;
+ double *cd = (double *)inp[ii].out_data_img;
+ for (unsigned int i = 0; i < row; i++)
{
- for(unsigned int j=0;j<col;j++)
+ for (unsigned int j = 0; j < col; j++)
{
- rd[k]=real(cmOut(k));
- cd[k]=imag(cmOut(k));
+ rd[k] = real(cmOut(k));
+ cd[k] = imag(cmOut(k));
//std::cout << "out img "<< k << " is :" << (double)imag(cmOut(k)) << '\n';
k++;
}
}
}
+ //Format Struct data
+ else if(out(ii).isstruct()){
+ inp[ii].is_out_struct = 1;
+
+ octave_scalar_map outOctaveStruct = out(ii).scalar_map_value();
+
+ int structLen = outOctaveStruct.nfields();
+ inp[ii].n_out_struct_len = structLen;
+
+ inp[ii].out_struct = (FUNCSTRUCT *) malloc(sizeof(FUNCSTRUCT) * structLen);
+ FUNCSTRUCT* outStruct = inp[ii].out_struct;
+
+ octave_scalar_map::iterator idx = outOctaveStruct.begin();
+ int j = 0;
+
+ // std::cout << "data in fun.cpp\n";
+ // populating structure
+ while (idx != outOctaveStruct.end()){
+ std::string currKey = outOctaveStruct.key(idx);
+ octave_value currValue = outOctaveStruct.contents(idx);
+
+ // storing key by converting string to wchar_t* for scilab
+ outStruct[j].key = malloc(sizeof(wchar_t) * (currKey.length() + 1));
+ mbstowcs((wchar_t *) outStruct[j].key, currKey.c_str(), currKey.length() + 1);
+
+ // storing value
+ if (currValue.iscomplex()){
+ outStruct[j].type = TYPE_COMPLEX;
+
+ ComplexMatrix currValueComplexMatrix(currValue.complex_matrix_value());
+
+ row = currValueComplexMatrix.rows();
+ col = currValueComplexMatrix.columns();
+ outStruct[j].rows = row;
+ outStruct[j].cols = col;
+
+ outStruct[j].dataReal = malloc(sizeof(double) * (row * col));
+ outStruct[j].dataImg = malloc(sizeof(double) * (row * col));
+
+ double* dReal = (double *) outStruct[j].dataReal;
+ double* dImg = (double *) outStruct[j].dataImg;
+
+ k = 0;
+ for (int r = 0; r < row; r++)
+ {
+ for (int c = 0; c < col; c++)
+ {
+ dReal[k] = real(currValueComplexMatrix(k));
+ dImg[k] = imag(currValueComplexMatrix(k));
+ k++;
+ }
+ }
+
+ }
+ else if (currValue.is_string()){
+ outStruct[j].type = TYPE_STRING;
+ std::string currValueStr = currValue.string_value();
+ outStruct[j].str = malloc(sizeof(wchar_t) * (currValueStr.length() + 1));
+ mbstowcs((wchar_t*) outStruct[j].str, currValueStr.c_str(), currValueStr.length() + 1);
+ }
+ else {
+ outStruct[j].type = TYPE_DOUBLE;
+
+ Matrix currValueMatrix(currValue.matrix_value());
+
+ row = currValueMatrix.rows();
+ col = currValueMatrix.columns();
+ outStruct[j].rows = row;
+ outStruct[j].cols = col;
+
+ outStruct[j].dataReal = malloc(sizeof(double) * (row * col));
+ double* dReal = (double *) outStruct[j].dataReal;
+
+ k = 0;
+ for (int r = 0; r < row; r++)
+ {
+ for (int c = 0; c < col; c++)
+ {
+ dReal[k] = currValueMatrix(k);
+ k++;
+ }
+ }
+ }
+
+ j++;
+ idx++;
+ }
+ }
+ // Format Matrix data
else
{
//std::cout << "out "<< ii<< " is NOT complex" << '\n';
- inp[ii].is_out_cmplx=0;
+ inp[ii].is_out_cmplx = 0;
Matrix mOut(out(ii).matrix_value());
row = mOut.rows();
col = mOut.columns();
inp[ii].n_out_rows = row;
inp[ii].n_out_cols = col;
- k=0;
- inp[ii].out_data_real = malloc(sizeof(double)*(row*col));
- double* dd = (double *)inp[ii].out_data_real;
- for(unsigned int i=0;i<row;i++)
+ k = 0;
+ inp[ii].out_data_real = malloc(sizeof(double) * (row * col));
+ double *dd = (double *)inp[ii].out_data_real;
+ for (unsigned int i = 0; i < row; i++)
{
- for(unsigned int j=0;j<col;j++)
+ for (unsigned int j = 0; j < col; j++)
{
- dd[k]=mOut(k);
+ dd[k] = mOut(k);
k++;
}
}
}
}
}
- catch (const octave::exit_exception& ex)
+ // Exception handling Octave
+ catch (const octave::exit_exception &ex)
{
std::cerr << "Octave interpreter exited with status = "
- << ex.exit_status () << std::endl;
+ << ex.exit_status() << std::endl;
return 1;
}
- catch (const octave::execution_exception&)
+ 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,37 +13,79 @@ //extern "C" int fun (double* answ, double* in1, int in1_row, std::string name, std::string opt); extern "C" -{ +{ - typedef enum - { - TYPE_DOUBLE, - TYPE_STRING, + /** + * + * @brief Enumeration for the data types suported by the fun() + * + */ + typedef enum { + 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; - typedef struct - { - FUNCTYPE type; - int n_in_rows; - int n_in_cols; - int n_out_rows; - int n_out_cols; - int is_in_cmplx; - int is_out_cmplx; - void* in_data_real; - void* in_data_img; - void* out_data_real; - void* out_data_img; - }FUNCARGS; - + /** + * @struct FUNCSTRUCT + * @brief Struct used to pass structs to Octave from the fun library + * @var type + * + */ + 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 - //char *package; //Name of octave package to be loaded - FUNCARGS *argument; -} FUNCCALL; + 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; /// 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; /// Return errors + //char *package; //Name of octave package to be loaded + 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); } |