int CreateCellVariable(int iVar, matvar_t *matVariable, int * parent, int item_position)
{
  static const char *fieldNames[] = {"ce", "dims","entries"};
  int nbFields = 3;
  int K = 0;
  int prodDims = 0;
  int valueIndex = 0, type;
  int * cell_addr = NULL;
  int * cell_entry_addr = NULL;
  matvar_t ** allData = NULL;
  SciErr _SciErr;

  /* Returned mlist initialization */
  if (parent==NULL)
    {
      _SciErr = createMList(pvApiCtx, iVar, nbFields, &cell_addr); MATIO_ERROR;
    }
  else
    {
      _SciErr = createMListInList(pvApiCtx, iVar, parent, item_position, nbFields, &cell_addr); MATIO_ERROR;
    }
 
  /* FIRST LIST ENTRY: fieldnames */
  _SciErr = createMatrixOfStringInList(pvApiCtx, iVar, cell_addr, 1, 1, nbFields, (char **)fieldNames); MATIO_ERROR;
  
  /* SECOND LIST ENTRY: Dimensions (int32 type) */
  if(matVariable->rank==2) /* Two dimensions */
    {
      _SciErr = createMatrixOfInteger32InList(pvApiCtx, iVar, cell_addr, 2, 1, matVariable->rank, matVariable->dims); MATIO_ERROR;
    }
  else /* 3 or more dimensions -> Scilab HyperMatrix */
    {
      type = I_INT32;
      CreateHyperMatrixVariable(iVar, MATRIX_OF_VARIABLE_SIZE_INTEGER_DATATYPE, 
				&type, &matVariable->rank, matVariable->dims, matVariable->data,
				NULL, cell_addr, 2);
    }

  /* ALL OTHER ENTRIES: Fields data */
  prodDims = 1;
  for (K=0; K<matVariable->rank; K++)
    {
      prodDims *= matVariable->dims[K];
    }

  allData = (matvar_t**) (matVariable->data);

  if (prodDims == 1) /* Scalar cell */
    {
      /* Create list entry in the stack */
      if (!CreateMatlabVariable(iVar, allData[0], cell_addr, 3)) /* Could not Create Variable */
	{
	  sciprint("Do not know how to read a variable of class %d.\n", allData[0]->class_type);
	}
    }
  else
    {
      _SciErr = createListInList(pvApiCtx, iVar, cell_addr, 3, prodDims, &cell_entry_addr); MATIO_ERROR;

      for (valueIndex = 0; valueIndex < prodDims; valueIndex++)
        {
          /* Create list entry in the stack */
          if (!CreateMatlabVariable(iVar, allData[valueIndex], cell_entry_addr, valueIndex+1)) /* Could not Create Variable */
            {
              sciprint("Do not know how to read a variable of class %d.\n", allData[valueIndex]->class_type);
            }
        }
    }
  
  return TRUE;
}
int CreateBooleanVariable(void *pvApiCtx, int iVar, matvar_t *matVariable, int * parent, int item_position)
{
    int nbRow = 0, nbCol = 0;
    int *piDims = NULL;
    int * intPtr = NULL;
    double * dblPtr = NULL;
    int K = 0;
    SciErr sciErr;

    if (matVariable->rank == 2) /* 2-D array */
    {
        nbRow = (int)matVariable->dims[0];
        nbCol = (int)matVariable->dims[1];

        if (nbRow * nbCol != 0)
        {
            if ((intPtr = (int*) MALLOC(sizeof(int) * nbRow * nbCol)) == NULL)
            {
                Scierror(999, _("%s: No more memory.\n"), "CreateBooleanVariable");
                return FALSE;
            }

            for (K = 0; K < nbRow * nbCol; K++)
            {
                intPtr[K] = ((unsigned char*)matVariable->data)[K];
            }

            if (parent == NULL)
            {
                sciErr = createMatrixOfBoolean(pvApiCtx, iVar, nbRow, nbCol, intPtr);
                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }
            }
            else
            {
                sciErr = createMatrixOfBooleanInList(pvApiCtx, iVar, parent, item_position, nbRow, nbCol, intPtr);
                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }
            }

            FREE(intPtr);
        }
        else
        {
            if ((dblPtr = (double *)MALLOC(sizeof(double) * nbRow * nbCol)) == NULL)
            {
                Scierror(999, _("%s: No more memory.\n"), "CreateBooleanVariable");
                return FALSE;
            }

            for (K = 0; K < nbRow * nbCol; K++)
            {
                dblPtr[K] = ((unsigned char*)matVariable->data)[K];
            }

            if (parent == NULL)
            {
                sciErr = createMatrixOfDouble(pvApiCtx, iVar, nbRow, nbCol, dblPtr);
                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }
            }
            else
            {
                sciErr = createMatrixOfDoubleInList(pvApiCtx, iVar, parent, item_position, nbRow, nbCol, dblPtr);
                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }
            }

            FREE(dblPtr);
        }
    }
    else /* Multi-dimension array -> Scilab HyperMatrix */
    {
        piDims = (int*) MALLOC(matVariable->rank * sizeof(int));
        if (piDims == NULL)
        {
            Scierror(999, _("%s: No more memory.\n"), "CreateBooleanVariable");
            return FALSE;
        }
        for (K = 0; K < matVariable->rank; K++)
        {
            piDims[K] = (int)matVariable->dims[K];
        }

        CreateHyperMatrixVariable(pvApiCtx, iVar, MATRIX_OF_BOOLEAN_DATATYPE,  NULL, &matVariable->rank, piDims, (double*)matVariable->data, NULL, parent, item_position);

        FREE(piDims);
    }

    return TRUE;
}
int CreateIntegerVariable(void *pvApiCtx, int iVar, int integerType, matvar_t *matVariable, int * parent, int item_position)
{
    int nbRow, nbCol, i;
    SciErr sciErr;
    char * tmp_int8 = NULL;
    short * tmp_int16 = NULL;
    int * tmp_int32 = NULL;
    int *piDims = NULL;
    unsigned char * tmp_uint8 = NULL;
    unsigned short * tmp_uint16 = NULL;
    unsigned int * tmp_uint32 = NULL;
#ifdef __SCILAB_INT64__
    long long * tmp_int64 = NULL;
    unsigned long long * tmp_uint64 = NULL;
#endif
    int iSize = 0;

    // Matrix dimensions
    nbRow = (int)matVariable->dims[0];
    nbCol = (int)matVariable->dims[1];
    iSize = nbRow * nbCol;

    if (iSize == 0)
    {
        double dblReal = 0;
        SciErr sciErr = createMatrixOfDouble(pvApiCtx, iVar, 0, 0, &dblReal);
        if (sciErr.iErr)
        {
            printError(&sciErr, 0);
            Scierror(999, _("%s: Memory allocation error.\n"), "CreateIntegerVariable");
            return FALSE;
        }

        return TRUE;
    }

    if (matVariable->rank == 2) /* 2-D array */
    {
        switch (integerType)
        {
            case SCI_INT8:
            {
                tmp_int8 = (char *)MALLOC(iSize * sizeof(char));

                if (tmp_int8 == NULL)
                {
                    Scierror(999, _("%s: No more memory.\n"), "CreateIntegerVariable");
                    return FALSE;
                }
                for (i = 0; i < iSize; i++)
                {
                    tmp_int8[i] = ((char *)matVariable->data)[i];
                }

                if (parent == NULL)
                {
                    sciErr = createMatrixOfInteger8(pvApiCtx, iVar, nbRow, nbCol, tmp_int8);
                }
                else
                {
                    sciErr = createMatrixOfInteger8InList(pvApiCtx, iVar, parent, item_position, nbRow, nbCol, tmp_int8);
                }

                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }

                FREE(tmp_int8);
            }
            break;
            case SCI_INT16:
            {

                tmp_int16 = (short *)MALLOC(iSize * sizeof(short));
                if (tmp_int16 == NULL)
                {
                    Scierror(999, _("%s: No more memory.\n"), "CreateIntegerVariable");
                    return FALSE;
                }

                for (i = 0; i < iSize; i++)
                {
                    tmp_int16[i] = ((short *)matVariable->data)[i];
                }


                if (parent == NULL)
                {
                    sciErr = createMatrixOfInteger16(pvApiCtx, iVar, nbRow, nbCol, tmp_int16);
                }
                else
                {
                    sciErr = createMatrixOfInteger16InList(pvApiCtx, iVar, parent, item_position, nbRow, nbCol, tmp_int16);
                }

                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }


                FREE(tmp_int16);
            }
            break;
            case SCI_INT32:
            {
                tmp_int32 = (int *)MALLOC(iSize * sizeof(int));

                if (tmp_int32 == NULL)
                {
                    Scierror(999, _("%s: No more memory.\n"), "CreateIntegerVariable");
                    return FALSE;
                }

                for (i = 0; i < iSize; i++)
                {
                    tmp_int32[i] = ((int *)matVariable->data)[i];
                }


                if (parent == NULL)
                {
                    sciErr = createMatrixOfInteger32(pvApiCtx, iVar, nbRow, nbCol, tmp_int32);
                }
                else
                {
                    sciErr = createMatrixOfInteger32InList(pvApiCtx, iVar, parent, item_position, nbRow, nbCol, tmp_int32);
                }

                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }


                FREE(tmp_int32);
            }
            break;
#ifdef __SCILAB_INT64__
            case SCI_INT64:
            {
                tmp_int64 = (long long *)MALLOC(iSize * sizeof(long long));
                if (tmp_int64 == NULL)
                {
                    Scierror(999, _("%s: No more memory.\n"), "CreateIntegerVariable");
                    return FALSE;
                }
                for (i = 0; i < iSize; i++)
                {
                    tmp_int64[i] = ((long long *)matVariable->data)[i];
                }


                if (parent == NULL)
                {
                    sciErr = createMatrixOfInteger64(pvApiCtx, iVar, nbRow, nbCol, tmp_int64);
                }
                else
                {
                    sciErr = createMatrixOfInteger64InList(pvApiCtx, iVar, parent, item_position, nbRow, nbCol, tmp_int64);
                }

                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }


                FREE(tmp_int64);
            }
            break;
#endif
            case SCI_UINT8:
            {
                tmp_uint8 = (unsigned char *)MALLOC(iSize * sizeof(unsigned char));
                if (tmp_uint8 == NULL)
                {
                    Scierror(999, _("%s: No more memory.\n"), "CreateIntegerVariable");
                    return FALSE;
                }
                for (i = 0; i < iSize; i++)
                {
                    tmp_uint8[i] = ((unsigned char *)matVariable->data)[i];
                }


                if (parent == NULL)
                {
                    sciErr = createMatrixOfUnsignedInteger8(pvApiCtx, iVar, nbRow, nbCol, tmp_uint8);
                }
                else
                {
                    sciErr = createMatrixOfUnsignedInteger8InList(pvApiCtx, iVar, parent, item_position, nbRow, nbCol, tmp_uint8);
                }

                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }


                FREE(tmp_uint8);
            }
            break;
            case SCI_UINT16:
            {
                tmp_uint16 = (unsigned short *)MALLOC(iSize * sizeof(unsigned short));
                if (tmp_uint16 == NULL)
                {
                    Scierror(999, _("%s: No more memory.\n"), "CreateIntegerVariable");
                    return FALSE;
                }
                for (i = 0; i < iSize; i++)
                {
                    tmp_uint16[i] = ((unsigned short *)matVariable->data)[i];
                }

                if (parent == NULL)
                {
                    sciErr = createMatrixOfUnsignedInteger16(pvApiCtx, iVar, nbRow, nbCol, tmp_uint16);
                }
                else
                {
                    sciErr = createMatrixOfUnsignedInteger16InList(pvApiCtx, iVar, parent, item_position, nbRow, nbCol, tmp_uint16);
                }

                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }

                FREE(tmp_uint16);
            }
            break;
            case SCI_UINT32:
            {
                tmp_uint32 = (unsigned int *)MALLOC(iSize * sizeof(unsigned int));
                if (tmp_uint32 == NULL)
                {
                    Scierror(999, _("%s: No more memory.\n"), "CreateIntegerVariable");
                    return FALSE;
                }
                for (i = 0; i < iSize; i++)
                {
                    tmp_uint32[i] = ((unsigned int *)matVariable->data)[i];
                }


                if (parent == NULL)
                {
                    sciErr = createMatrixOfUnsignedInteger32(pvApiCtx, iVar, nbRow, nbCol, tmp_uint32);
                }
                else
                {
                    sciErr = createMatrixOfUnsignedInteger32InList(pvApiCtx, iVar, parent, item_position, nbRow, nbCol, tmp_uint32);
                }

                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }

                FREE(tmp_uint32);
            }
            break;
#ifdef __SCILAB_INT64__
            case SCI_UINT64:
            {
                tmp_uint64 = (unsigned long long *)MALLOC(iSize * sizeof(unsigned long long));
                if (tmp_uint64 == NULL)
                {
                    Scierror(999, _("%s: No more memory.\n"), "CreateIntegerVariable");
                    return FALSE;
                }
                for (i = 0; i < iSize; i++)
                {
                    tmp_uint64[i] = ((unsigned long long *)matVariable->data)[i];
                }

                if (parent == NULL)
                {
                    sciErr = createMatrixOfUnsignedInteger64(pvApiCtx, iVar, nbRow, nbCol, tmp_uint64);
                }
                else
                {
                    sciErr = createMatrixOfUnsignedInteger64InList(pvApiCtx, iVar, parent, item_position, nbRow, nbCol, tmp_uint64);
                }

                if (sciErr.iErr)
                {
                    printError(&sciErr, 0);
                    return 0;
                }


                FREE(tmp_uint64);
            }
            break;
#endif
        }
    }
    else /* Multi-dimension array -> Scilab HyperMatrix */
    {
        piDims = (int*) MALLOC(matVariable->rank * sizeof(int));
        if (piDims == NULL)
        {
            Scierror(999, _("%s: No more memory.\n"), "CreateBooleanVariable");
            return FALSE;
        }
        for (i = 0; i < matVariable->rank; i++)
        {
            piDims[i] = (int)matVariable->dims[i];
        }

        CreateHyperMatrixVariable(pvApiCtx, iVar, matVariable->class_type, &integerType, &matVariable->rank,
                                  piDims, matVariable , parent, item_position);

        FREE(piDims);
    }

    return TRUE;
}
int CreateStructVariable(void *pvApiCtx, int iVar, matvar_t *matVariable, int * parent, int item_position)
{
    char **fieldNames = NULL;
    int nbFields = 0;
    int fieldIndex = 0;
    int K = 0;
    int prodDims = 0;
    int valueIndex = 0;
    matvar_t *fieldMatVar = NULL;
    matvar_t ** allData = NULL;
    int * cell_addr = NULL;
    int * cell_entry_addr = NULL;
    int type;
    SciErr sciErr;
    int *piDims = NULL;
    int i = 0;

    /* Fields of the struct */
    nbFields = 2; /* "st" "dims" */
    nbFields += Mat_VarGetNumberOfFields(matVariable);

    fieldNames = (char**) MALLOC(sizeof(char*) * nbFields);
    if (fieldNames == NULL)
    {
        Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
        return FALSE;
    }

    fieldNames[0] = strdup("st");
    if (fieldNames[0] == NULL)
    {
        Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
        return FALSE;
    }
    fieldNames[1] = strdup("dims");
    if (fieldNames[1] == NULL)
    {
        Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
        return FALSE;
    }

    for (fieldIndex = 1; fieldIndex < nbFields - 1; fieldIndex++)
    {
        fieldMatVar = Mat_VarGetStructField(matVariable, &fieldIndex, MAT_BY_INDEX, 0);
        fieldNames[fieldIndex + 1] = strdup(fieldMatVar->name);
        if (fieldNames[fieldIndex + 1] == NULL)
        {
            Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
            return FALSE;
        }
    }

    /* Returned mlist initialization */
    if (parent == NULL)
    {
        sciErr = createMList(pvApiCtx, iVar, nbFields, &cell_addr);
        if (sciErr.iErr)
        {
            printError(&sciErr, 0);
            return 0;
        }
    }
    else
    {
        sciErr = createMListInList(pvApiCtx, iVar, parent, item_position, nbFields, &cell_addr);
        if (sciErr.iErr)
        {
            printError(&sciErr, 0);
            return 0;
        }
    }

    /* FIRST LIST ENTRY: fieldnames */
    sciErr = createMatrixOfStringInList(pvApiCtx, iVar, cell_addr, 1, 1, nbFields, fieldNames);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 0;
    }

    /* SECOND LIST ENTRY: Dimensions (int32 type) */
    if (nbFields == 2) /* Empty struct must have size 0x0 in Scilab */
    {
        matVariable->dims[0] = 0;
        matVariable->dims[1] = 0;
    }

    piDims = (int *) MALLOC(matVariable->rank * sizeof(int));
    for (i = 0 ; i < matVariable->rank ; ++i)
    {
        piDims[i] = (int)matVariable->dims[i];
    }

    if (matVariable->rank == 2) /* Two dimensions */
    {
        sciErr = createMatrixOfInteger32InList(pvApiCtx, iVar, cell_addr, 2, 1, matVariable->rank, piDims);
        if (sciErr.iErr)
        {
            printError(&sciErr, 0);
            return 0;
        }
    }
    else /* 3 or more dimensions -> Scilab HyperMatrix */
    {
        type = I_INT32;
        CreateHyperMatrixVariable(pvApiCtx, iVar, MATRIX_OF_VARIABLE_SIZE_INTEGER_DATATYPE,
                                  &type, &matVariable->rank, piDims, (double*)matVariable->data,
                                  NULL, cell_addr, 2);
    }

    FREE(piDims);

    /* ALL OTHER ENTRIES: Fields data */
    prodDims = 1;
    for (K = 0; K < matVariable->rank; K++)
    {
        prodDims *= (int)matVariable->dims[K];
    }

    allData = (matvar_t**) (matVariable->data);

    if (prodDims == 1) /* Scalar struct */
    {
        for (fieldIndex = 0; fieldIndex < nbFields - 2; fieldIndex++)
        {
            /* Create list entry in the stack */
            if (!CreateMatlabVariable(pvApiCtx, iVar, allData[fieldIndex], cell_addr, fieldIndex + 3)) /* Could not Create Variable */
            {
                if (allData[fieldIndex]->class_type != 0) /* class is 0 for not initialized fields */
                {
                    sciprint("Do not know how to read a variable of class %d.\n", allData[fieldIndex]->class_type);
                }
            }
        }
    }
    else
    {
        for (fieldIndex = 0; fieldIndex < nbFields - 2; fieldIndex++)
        {
            sciErr = createListInList(pvApiCtx, iVar, cell_addr, fieldIndex + 3, prodDims, &cell_entry_addr);
            if (sciErr.iErr)
            {
                printError(&sciErr, 0);
                return 0;
            }

            for (valueIndex = 0; valueIndex < prodDims; valueIndex++)
            {
                /* Create list entry in the stack */
                if (!CreateMatlabVariable(pvApiCtx, iVar, allData[(fieldIndex) + (nbFields - 2)*valueIndex], cell_entry_addr, valueIndex + 1)) /* Could not Create Variable */
                {
                    if (allData[(fieldIndex) + (nbFields - 2)*valueIndex]->class_type != 0) /* class is 0 for not initialized fields */
                    {
                        sciprint("Do not know how to read a variable of class %d.\n", allData[(fieldIndex) + (nbFields - 2)*valueIndex]->class_type);
                    }
                }
            }
        }
    }

    freeArrayOfString(fieldNames, nbFields);

    return TRUE;
}