Exemplo n.º 1
0
 bool isValidRange(TreeNode* cur, TreeNode* minNode, TreeNode* maxNode){
     if (cur == nullptr) return true;
     if (maxNode&&cur->val>=maxNode->val) return false;
     if (minNode&&cur->val<=minNode->val) return false;
     
     bool leftvalid = true;
     bool rightvalid = true;
     if(cur->left){
         leftvalid = isValidRange(cur->left,minNode, cur);
     }
     if(cur->right){
             rightvalid = isValidRange(cur->right, cur, maxNode);
     }
     return leftvalid&&rightvalid;
 }
Exemplo n.º 2
0
/* expand: populates s2 with the expanded groups in s1 */
void expand(char s1[], char s2[])
{
    int i;                  /* counter for s1 */
    int j;                  /* counter for s2 */
    int k;                  /* counter when expanding the group */
    int thePrevRangeEnd;    /* stores the index of the last valid range */
    int cur, next, prev;    /* hold current, previous and next values */

    for (i = j = 0; (cur = s1[i]) != '\0'; ++i) {
        
        /* only look for hyphens */
        if (isHyphen(cur)) { 
            
            if (isLeadingOrTrailing(s1, i)) {
                /* it is a leading or trailing hyphen so copy it */
                s2[j++] = cur;
            
            } else { 
                /* it is NOT leading or trailing so determine of it is part
                of a group */
                prev = s1[i-1];
                next = s1[i+1];

                /* check that the range is valid before going any further */
                if (isValidRange(prev, next)) {

                    /* if we are the 2nd+ hyphen in a group e.g. between 
                    b and c in "a-b-c" then skip the first char in the 
                    group because we already copied it when dealing with the
                    a-b part */
                    if (thePrevRangeEnd == (i - 1)) {
                       ++prev;
                    }

                    /* now loop through each character in the range and add 
                    it to s2 */
                    for (k = prev; k <= next; ++k) {
                        s2[j++] = k;   
                    }

                    /* update the previous range end */
                    thePrevRangeEnd = i+1;
                }
            }
        }
    }

    /* we've finished expanding so close add in the terminator char */
    s2[j++] = '\0';
}
Exemplo n.º 3
0
// =============================================================================
complexArray *getRangeAsComplexArray(const complexArray *pComplex,
                                     int nbRows, int nbCols,
                                     const int *iRange,
                                     int *returnedNbRows, int *returnedNbCols)
{
    if (isValidRange(iRange, SIZE_ARRAY_RANGE))
    {
        int R1, C1, R2, C2;
        int rangeSize;

        getSubIndices(iRange, &R1, &R2, &C1, &C2 );

        *returnedNbRows = getRangeSize(&R1, &R2, nbRows);
        *returnedNbCols = getRangeSize(&C1, &C2, nbCols);

        rangeSize = (*returnedNbRows) * (*returnedNbCols);
        if (rangeSize > 0)
        {
            complexArray *newComplexArray =
                createComplexArrayEmpty(rangeSize);
            if (newComplexArray != NULL)
            {
                int i = 0;
                int j = 0;
                int k = 0;

                newComplexArray->isComplex = pComplex->isComplex;

                for (j = C1 - 1 ; j < C2 ; j++)
                {
                    for (i = R1 - 1 ; i < R2 ; i++)
                    {
                        newComplexArray->realPart[k] = pComplex->realPart[i + (nbRows * j)];
                        if (pComplex->isComplex)
                        {
                            newComplexArray->imagPart[k] = pComplex->imagPart[i + (nbRows * j)];
                        }
                        k++;
                    }
                }
            }
            return newComplexArray;
        }
        // range is empty, calling function should raise an out of bound error
    }
    return NULL;
}
Exemplo n.º 4
0
static bool genericParseNumber(const CharType*& cursor, const CharType* end, FloatType& number, WhitespaceMode mode)
{
    FloatType integer, decimal, frac, exponent;
    int sign, expsign;

    exponent = 0;
    integer = 0;
    frac = 1;
    decimal = 0;
    sign = 1;
    expsign = 1;

    if (mode & AllowLeadingWhitespace)
        skipOptionalSVGSpaces(cursor, end);

    const CharType* ptr = cursor;
    // read the sign
    if (ptr < end && *ptr == '+')
        ptr++;
    else if (ptr < end && *ptr == '-') {
        ptr++;
        sign = -1;
    }

    if (ptr == end || ((*ptr < '0' || *ptr > '9') && *ptr != '.'))
        // The first character of a number must be one of [0-9+-.]
        return false;

    // read the integer part, build right-to-left
    const CharType* digitsStart = ptr;
    while (ptr < end && *ptr >= '0' && *ptr <= '9')
        ++ptr; // Advance to first non-digit.

    if (ptr != digitsStart) {
        const CharType* ptrScanIntPart = ptr - 1;
        FloatType multiplier = 1;
        while (ptrScanIntPart >= digitsStart) {
            integer += multiplier * static_cast<FloatType>(*(ptrScanIntPart--) - '0');
            multiplier *= 10;
        }
        // Bail out early if this overflows.
        if (!isValidRange(integer))
            return false;
    }

    if (ptr < end && *ptr == '.') { // read the decimals
        ptr++;

        // There must be a least one digit following the .
        if (ptr >= end || *ptr < '0' || *ptr > '9')
            return false;

        while (ptr < end && *ptr >= '0' && *ptr <= '9')
            decimal += (*(ptr++) - '0') * (frac *= static_cast<FloatType>(0.1));
    }

    // When we get here we should have consumed either a digit for the integer
    // part or a fractional part (with at least one digit after the '.'.)
    ASSERT(digitsStart != ptr);

    // read the exponent part
    if (ptr + 1 < end && (*ptr == 'e' || *ptr == 'E')
        && (ptr[1] != 'x' && ptr[1] != 'm')) {
        ptr++;

        // read the sign of the exponent
        if (*ptr == '+')
            ptr++;
        else if (*ptr == '-') {
            ptr++;
            expsign = -1;
        }

        // There must be an exponent
        if (ptr >= end || *ptr < '0' || *ptr > '9')
            return false;

        while (ptr < end && *ptr >= '0' && *ptr <= '9') {
            exponent *= static_cast<FloatType>(10);
            exponent += *ptr - '0';
            ptr++;
        }
        // Make sure exponent is valid.
        if (!isValidRange(exponent) || exponent > std::numeric_limits<FloatType>::max_exponent)
            return false;
    }

    number = integer + decimal;
    number *= sign;

    if (exponent)
        number *= static_cast<FloatType>(pow(10.0, expsign * static_cast<int>(exponent)));

    // Don't return Infinity() or NaN().
    if (!isValidRange(number))
        return false;

    // A valid number has been parsed. Commit cursor.
    cursor = ptr;

    if (mode & AllowTrailingWhitespace)
        skipOptionalSVGSpacesOrDelimiter(cursor, end);

    return true;
}
Exemplo n.º 5
0
static bool genericParseNumber(const CharType*& ptr, const CharType* end, FloatType& number, bool skip)
{
    FloatType integer, decimal, frac, exponent;
    int sign, expsign;
    const CharType* start = ptr;

    exponent = 0;
    integer = 0;
    frac = 1;
    decimal = 0;
    sign = 1;
    expsign = 1;

    // read the sign
    if (ptr < end && *ptr == '+')
        ptr++;
    else if (ptr < end && *ptr == '-') {
        ptr++;
        sign = -1;
    }

    if (ptr == end || ((*ptr < '0' || *ptr > '9') && *ptr != '.'))
        // The first character of a number must be one of [0-9+-.]
        return false;

    // read the integer part, build right-to-left
    const CharType* ptrStartIntPart = ptr;
    while (ptr < end && *ptr >= '0' && *ptr <= '9')
        ++ptr; // Advance to first non-digit.

    if (ptr != ptrStartIntPart) {
        const CharType* ptrScanIntPart = ptr - 1;
        FloatType multiplier = 1;
        while (ptrScanIntPart >= ptrStartIntPart) {
            integer += multiplier * static_cast<FloatType>(*(ptrScanIntPart--) - '0');
            multiplier *= 10;
        }
        // Bail out early if this overflows.
        if (!isValidRange(integer))
            return false;
    }

    if (ptr < end && *ptr == '.') { // read the decimals
        ptr++;

        // There must be a least one digit following the .
        if (ptr >= end || *ptr < '0' || *ptr > '9')
            return false;

        while (ptr < end && *ptr >= '0' && *ptr <= '9')
            decimal += (*(ptr++) - '0') * (frac *= static_cast<FloatType>(0.1));
    }

    // read the exponent part
    if (ptr != start && ptr + 1 < end && (*ptr == 'e' || *ptr == 'E')
        && (ptr[1] != 'x' && ptr[1] != 'm')) {
        ptr++;

        // read the sign of the exponent
        if (*ptr == '+')
            ptr++;
        else if (*ptr == '-') {
            ptr++;
            expsign = -1;
        }

        // There must be an exponent
        if (ptr >= end || *ptr < '0' || *ptr > '9')
            return false;

        while (ptr < end && *ptr >= '0' && *ptr <= '9') {
            exponent *= static_cast<FloatType>(10);
            exponent += *ptr - '0';
            ptr++;
        }
        // Make sure exponent is valid.
        if (!isValidRange(exponent) || exponent > std::numeric_limits<FloatType>::max_exponent)
            return false;
    }

    number = integer + decimal;
    number *= sign;

    if (exponent)
        number *= static_cast<FloatType>(pow(10.0, expsign * static_cast<int>(exponent)));

    // Don't return Infinity() or NaN().
    if (!isValidRange(number))
        return false;

    if (start == ptr)
        return false;

    if (skip)
        skipOptionalSVGSpacesOrDelimiter(ptr, end);

    return true;
}
Exemplo n.º 6
0
// =============================================================================
int sci_csvTextScan(char *fname, unsigned long fname_len)
{
    SciErr sciErr;
    int iErr = 0;
    int i = 0;

    int *piAddressVarOne = NULL;
    int m1 = 0, n1 = 0;
    int iType1 = 0;

    char **text = NULL;
    int *lengthText = NULL;
    int nbLines = 0;

    char *separator = NULL;
    char *decimal = NULL;
    char *conversion = NULL;

    double * dRealValues = NULL;

    int *iRange = NULL;
    int haveRange = 0;

    csvResult *result = NULL;

    CheckRhs(1, 5);
    CheckLhs(1, 1);

    if (Rhs == 5)
    {
        int m5 = 0, n5 = 0;

        iRange = csv_getArgumentAsMatrixofIntFromDouble(pvApiCtx, 5, fname, &m5, &n5, &iErr);
        if (iErr)
        {
            return 0;
        }

        if ((m5 * n5 != SIZE_RANGE_SUPPORTED) )
        {
            if (iRange)
            {
                FREE(iRange);
                iRange = NULL;
            }
            Scierror(999, _("%s: Wrong size for input argument #%d: Four entries expected.\n"), fname, 5);
            return 0;
        }

        if ((m5 != 1) && (n5 != 1))
        {
            if (iRange)
            {
                FREE(iRange);
                iRange = NULL;
            }
            Scierror(999, _("%s: Wrong size for input argument #%d: A column or row vector expected.\n"), fname, 5);
            return 0;
        }

        if (isValidRange(iRange, m5 * n5))
        {
            haveRange = 1;
        }
        else
        {
            if (iRange)
            {
                FREE(iRange);
                iRange = NULL;
            }
            Scierror(999, _("%s: Wrong value for input argument #%d: Inconsistent range.\n"), fname, 5);
            return 0;
        }
    }

    if (Rhs >= 4)
    {
        conversion = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 4, fname, getCsvDefaultConversion(), &iErr);
        if (iErr)
        {
            if (iRange)
            {
                FREE(iRange);
                iRange = NULL;
            }
            return 0;
        }

        if (!((strcmp(conversion, CONVTOSTR) == 0) || (strcmp(conversion, CONVTODOUBLE) == 0)))
        {
            if (iRange)
            {
                FREE(iRange);
                iRange = NULL;
            }
            if (conversion)
            {
                FREE(conversion);
                conversion = NULL;
            }

            Scierror(999, _("%s: Wrong value for input argument #%d: '%s' or '%s' string expected.\n"), fname, 4, "double", "string");
            return 0;
        }
    }
    else
    {
        conversion = strdup(getCsvDefaultConversion());
    }

    if (Rhs >= 3)
    {
        decimal = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 3, fname, getCsvDefaultDecimal(), &iErr);
        if (iErr)
        {
            if (iRange)
            {
                FREE(iRange);
                iRange = NULL;
            }
            if (conversion)
            {
                FREE(conversion);
                conversion = NULL;
            }
            return 0;
        }

        if (decimal[0] != '.' && decimal[0] != ',')
        {
            if (iRange)
            {
                FREE(iRange);
                iRange = NULL;
            }
            if (conversion)
            {
                FREE(conversion);
                conversion = NULL;
            }

            Scierror(999, _("%s: Wrong value for input argument #%d: '%s' or '%s' string expected.\n"), fname, 3, ",", ".");
            return 0;
        }
    }
    else
    {
        decimal = strdup(getCsvDefaultDecimal());
    }

    if (Rhs >= 2)
    {
        separator = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 2, fname, getCsvDefaultSeparator(), &iErr);
        if (iErr)
        {
            if (iRange)
            {
                FREE(iRange);
                iRange = NULL;
            }
            if (decimal)
            {
                FREE(decimal);
                decimal = NULL;
            }
            if (conversion)
            {
                FREE(conversion);
                conversion = NULL;
            }
            return 0;
        }
    }
    else
    {
        separator = strdup(getCsvDefaultSeparator());
    }

    if (!csv_isRowVector(pvApiCtx, 1) &&
            !csv_isColumnVector(pvApiCtx, 1) &&
            !csv_isScalar(pvApiCtx, 1))
    {
        if (iRange)
        {
            FREE(iRange);
            iRange = NULL;
        }
        if (separator)
        {
            FREE(separator);
            separator = NULL;
        }
        if (decimal)
        {
            FREE(decimal);
            decimal = NULL;
        }
        if (conversion)
        {
            FREE(conversion);
            conversion = NULL;
        }
        Scierror(999, _("%s: Wrong size for input argument #%d: Vector string expected.\n"), fname, 1);
        return 0;
    }

    text = csv_getArgumentAsMatrixOfString(pvApiCtx, 1, fname, &m1, &n1, &iErr);
    if (iErr)
    {
        if (iRange)
        {
            FREE(iRange);
            iRange = NULL;
        }
        if (separator)
        {
            FREE(separator);
            separator = NULL;
        }
        if (decimal)
        {
            FREE(decimal);
            decimal = NULL;
        }
        if (conversion)
        {
            FREE(conversion);
            conversion = NULL;
        }
        return 0;
    }

    nbLines = m1 * n1;
    result = csvTextScan((const char**)text, nbLines, separator, decimal);

    if (text)
    {
        if (separator)
        {
            FREE(separator);
            separator = NULL;
        }
        freeArrayOfString(text, nbLines);
        text = NULL;
    }

    if (separator)
    {
        FREE(separator);
        separator = NULL;
    }

    if (result)
    {
        switch (result->err)
        {
            case CSV_READ_SEPARATOR_DECIMAL_EQUAL:
            {
                Scierror(999, _("%s: separator and decimal must have different values.\n"), fname);
            }
            break;

            case CSV_READ_NO_ERROR:
            {
                if (strcmp(conversion, CONVTOSTR) == 0)
                {
                    if (haveRange)
                    {
                        int newM = 0;
                        int newN = 0;

                        char **pStrRange = getRangeAsString((const char**)result->pstrValues, result->m, result->n, iRange, &newM, &newN);
                        if (pStrRange)
                        {
                            sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, newM, newN, pStrRange);
                            freeArrayOfString(pStrRange, newM * newN);
                        }
                        else
                        {
                            Scierror(999, _("%s: Memory allocation error.\n"), fname);
                        }

                    }
                    else
                    {
                        sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, result->m, result->n, result->pstrValues);
                    }
                }
                else /* to double */
                {
                    stringToComplexError ierr = STRINGTOCOMPLEX_ERROR;
                    csv_complexArray *ptrCsvComplexArray = stringsToCsvComplexArray((const char**)result->pstrValues, result->m * result->n, decimal, TRUE, &ierr);
                    if (ptrCsvComplexArray == NULL)
                    {
                        freeCsvResult(result);
                        if (decimal)
                        {
                            FREE(decimal);
                            decimal = NULL;
                        }
                        if (conversion)
                        {
                            FREE(conversion);
                            conversion = NULL;
                        }
                        if (iRange)
                        {
                            FREE(iRange);
                            iRange = NULL;
                        }
                        if (ierr == STRINGTOCOMPLEX_ERROR)
                        {
                            Scierror(999, _("%s: can not convert data.\n"), fname);
                        }
                        else
                        {
                            Scierror(999, _("%s: Memory allocation error.\n"), fname);
                        }
                        return 0;
                    }

                    switch (ierr)
                    {
                        case STRINGTOCOMPLEX_NOT_A_NUMBER:
                        case STRINGTOCOMPLEX_NO_ERROR:
                        {
                            if (haveRange)
                            {
                                int newM = 0;
                                int newN = 0;
                                csv_complexArray *csvComplexRange = getRangeAsCsvComplexArray(ptrCsvComplexArray, result->m, result->n, iRange, &newM, &newN);
                                if (csvComplexRange)
                                {
                                    if (csvComplexRange->isComplex)
                                    {
                                        sciErr = createComplexMatrixOfDouble(pvApiCtx, Rhs + 1, newM, newN, ptrCsvComplexArray->realPart, ptrCsvComplexArray->imagPart);
                                    }
                                    else
                                    {
                                        sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, newM, newN, csvComplexRange->realPart);
                                    }
                                    freeCsvComplexArray(csvComplexRange);
                                    csvComplexRange = NULL;
                                }
                                else
                                {
                                    Scierror(999, _("%s: Memory allocation error.\n"), fname);
                                }
                            }
                            else
                            {
                                if (ptrCsvComplexArray->isComplex)
                                {
                                    sciErr = createComplexMatrixOfDouble(pvApiCtx, Rhs + 1, result->m, result->n, ptrCsvComplexArray->realPart, ptrCsvComplexArray->imagPart);
                                }
                                else
                                {
                                    sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, result->m, result->n, ptrCsvComplexArray->realPart);
                                }
                            }
                            freeCsvComplexArray(ptrCsvComplexArray);
                            ptrCsvComplexArray = NULL;
                        }
                        break;

                        case STRINGTOCOMPLEX_MEMORY_ALLOCATION:
                        {
                            Scierror(999, _("%s: Memory allocation error.\n"), fname);
                        }
                        default:
                        case STRINGTOCOMPLEX_ERROR:
                        {
                            Scierror(999, _("%s: can not convert data.\n"), fname);
                        }
                    }
                }

                if (sciErr.iErr)
                {
                    freeCsvResult(result);
                    if (decimal)
                    {
                        FREE(decimal);
                        decimal = NULL;
                    }
                    if (conversion)
                    {
                        FREE(conversion);
                        conversion = NULL;
                    }
                    if (iRange)
                    {
                        FREE(iRange);
                        iRange = NULL;
                    }
                    printError(&sciErr, 0);
                    Scierror(17, _("%s: Memory allocation error.\n"), fname);
                    return 0;
                }
                else
                {
                    LhsVar(1) = Rhs + 1;
                    PutLhsVar();
                }
            }
            break;

            case CSV_READ_MEMORY_ALLOCATION:
            {
                Scierror(999, _("%s: Memory allocation error.\n"), fname);
            }
            break;

            case CSV_READ_COLUMNS_ERROR:
            {
                Scierror(999, _("%s: can not read text: Error in the column structure\n"), fname);
            }
            break;

            case CSV_READ_READLINES_ERROR:
            case CSV_READ_ERROR:
            {
                Scierror(999, _("%s: can not read text.\n"), fname);
            }
            break;
        }
    }
    else
    {
        Scierror(999, _("%s: Memory allocation error.\n"), fname);
    }
    freeCsvResult(result);
    if (decimal)
    {
        FREE(decimal);
        decimal = NULL;
    }
    if (conversion)
    {
        FREE(conversion);
        conversion = NULL;
    }
    if (iRange)
    {
        FREE(iRange);
        iRange = NULL;
    }

    return 0;
}
Exemplo n.º 7
0
void
calcForegroundPointReliability( const std::vector<float>          &ranges,
                                const AnnotatedPole               &fgPoint,
                                const ForegroundExtractor::Config &config,
                                double                             basePTruePositive,
                                double                             basePFalsePositive,
                                double                            &pTruePositive,
                                double                            &pFalsePositive )
{
    pTruePositive  = basePTruePositive;
    pFalsePositive = basePFalsePositive;

    // If a pole is close to clutter, don't trust it so much.
    assert ( fgPoint.distToClutter >= config.minForegroundBackgroundSeparation );
    if ( fgPoint.distToClutter < config.clearForegroundBackgroundSeparation )
    {
        double scale = 
            config.clearForegroundBackgroundSeparation -
            config.minForegroundBackgroundSeparation;
        double goodness = 
            (fgPoint.distToClutter - config.minForegroundBackgroundSeparation)/scale;
            
        // cout<<"TRACE(foregroundextractor.cpp): pole: " << toString(fgPoint) << ": goodness: " << goodness << endl;
        // cout<<"TRACE(foregroundextractor.cpp): base: pFalsePos/pTruePos: " << pFalsePos << "/" << pTruePos << endl;

        if ( goodness < 1 )
        {
            const double diff = pTruePositive - pFalsePositive;
            pFalsePositive += (1-goodness) * diff/2.0;
            pTruePositive  -= (1-goodness) * diff/2.0;

            // cout<<"TRACE(foregroundextractor.cpp):  --> pFalsePos/pTruePos: " << pFalsePos << "/" << pTruePos << endl;
        }
    }

    // If a pole consists of just a single point, don't trust it so much.
    if ( fgPoint.pole.startI == fgPoint.pole.endI )
    {
        //const double diff = pTruePositive_ - pFalsePositive_;
        const double diff = pTruePositive - pFalsePositive;
        pFalsePositive += diff/4.0;
        pTruePositive  -= diff/4.0;
    }
        
    // If there are non-returns either side, maybe this is a specular surface on which
    // we've gotten one lucky return.
    if ( (fgPoint.pole.startI > 0 &&
          fgPoint.pole.endI   < (int)(ranges.size())-1) &&
         ( !isValidRange( ranges[fgPoint.pole.startI-1], config.scannerConfig ) ||
           !isValidRange( ranges[fgPoint.pole.endI+1], config.scannerConfig ) ) )
    {
        //const double diff = pTruePositive_ - pFalsePositive_;
        const double diff = pTruePositive - pFalsePositive;
        pFalsePositive += diff/3.0;
        pTruePositive  -= diff/3.0;            
    }

    // At short ranges, you get fewer false positives
    if ( fgPoint.pole.range < config.reliableScannerRange )
    {
        pFalsePositive = MAX( 0.0, pFalsePositive-0.1 );
    }    
}
Exemplo n.º 8
0
 bool isValidBST(TreeNode* root) {
     
     return isValidRange(root, nullptr, nullptr);
 }
Exemplo n.º 9
0
/* ==================================================================== */
int sci_csvRead(char *fname, unsigned long fname_len)
{
    SciErr sciErr;
    int iErr = 0;
    int iErrEmpty = 0;

    char *filename = NULL;
    char *separator = NULL;
    char *decimal = NULL;
    char *conversion = NULL;
    int *iRange = NULL;
    int haveRange = 0;
    int header = 0;

    char **toreplace = NULL;
    int nbElementsToReplace = 0;

    char *regexp = NULL;
    int haveRegexp = 0;

    csvResult *result = NULL;

    double *dRealValues = NULL;

    sciErr.iErr = 0;

    CheckRhs(1, 8);
    CheckLhs(1, 2);

    if (Rhs == 8)
    {
        header = (int) csv_getArgumentAsScalarDouble(pvApiCtx, 8, fname, &iErr);
        if (iErr)
        {
            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, 0, &regexp);
            return 0;
        }
    }

    if (Rhs == 7)
    {
        int m7 = 0, n7 = 0;

        iRange = csv_getArgumentAsMatrixofIntFromDouble(pvApiCtx, 7, fname, &m7, &n7, &iErr);
        if (iErr)
        {
            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, 0, &regexp);
            return 0;
        }

        if ((m7 * n7 != SIZE_RANGE_SUPPORTED) )
        {
            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, 0, &regexp);
            Scierror(999, _("%s: Wrong size for input argument #%d: Four entries expected.\n"), fname, 7);
            return 0;
        }

        if ((m7 != 1) && (n7 != 1))
        {
            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, 0, &regexp);
            Scierror(999, _("%s: Wrong size for input argument #%d: A column or row vector expected.\n"), fname, 7);
            return 0;
        }

        if (isValidRange(iRange, m7 * n7))
        {
            haveRange = 1;
        }
        else
        {
            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, 0, &regexp);
            Scierror(999, _("%s: Wrong value for input argument #%d: Inconsistent range.\n"), fname, 7);
            return 0;
        }
    }


    if (Rhs >= 6)
    {
        regexp = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 6, fname, getCsvDefaultCommentsRegExp(), &iErr);
        if (regexp)
        {
            if (strcmp(regexp, "") == 0)
            {
                FREE(regexp);
                regexp = NULL;
            }
            else
            {
                haveRegexp = 1;
            }
        }

        if (iErr)
        {
            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, 0, &regexp);
            return 0;
        }
    }
    else
    {
        regexp = strdup(getCsvDefaultCommentsRegExp());
        if (regexp)
        {
            if (strcmp(regexp, "") == 0)
            {
                FREE(regexp);
                regexp = NULL;
            }
        }
    }

    if (Rhs >= 5)
    {
        if (csv_isEmpty(pvApiCtx, 5))
        {
            toreplace = NULL;
            nbElementsToReplace = 0;
        }
        else
        {
            int m5 = 0, n5 = 0;
            toreplace = csv_getArgumentAsMatrixOfString(pvApiCtx, 5, fname, &m5, &n5, &iErr);
            if (iErr)
            {
                freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, m5 * n5, &regexp);
                return 0;
            }

            if (n5 != 2)
            {
                freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, m5 * n5, &regexp);
                Scierror(999, _("%s: Wrong size for input argument #%d.\n"), fname, 5);
                return 0;
            }
            nbElementsToReplace = m5;
        }
    }
    else
    {
        toreplace = NULL;
        nbElementsToReplace = 0;
    }

    if (Rhs >= 4)
    {
        int iErr = 0;
        conversion = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 4, fname, getCsvDefaultConversion(), &iErr);
        if (iErr)
        {
            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
            return 0;
        }

        if (!((strcmp(conversion, CONVTOSTR) == 0) || (strcmp(conversion, CONVTODOUBLE) == 0)))
        {
            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
            Scierror(999, _("%s: Wrong value for input argument #%d: '%s' or '%s' string expected.\n"), fname, 4, "double", "string");
            return 0;
        }
    }
    else
    {
        /* read_csv is using a 'string' conversion while csvRead is doing
           a 'double' conversion */
        if (strcmp(fname, "read_csv") == 0)
        {
            conversion = (char*)MALLOC((strlen("string") + 1) * sizeof(char));
            strcpy(conversion, "string");
        }
        else
        {
            conversion = strdup(getCsvDefaultConversion());
        }
    }

    if (Rhs >= 3)
    {
        int iErr = 0;
        decimal = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 3, fname, getCsvDefaultDecimal(), &iErr);
        if (iErr)
        {
            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
            return 0;
        }
    }
    else
    {
        decimal = strdup(getCsvDefaultDecimal());
    }

    if (Rhs >= 2)
    {
        int iErr = 0;
        separator = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 2, fname, getCsvDefaultSeparator(), &iErr);
        if (iErr)
        {
            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
            return 0;
        }
    }
    else
    {
        separator = strdup(getCsvDefaultSeparator());
    }

    if (strcmp(separator, "\\t") == 0)
    {
        /* In Scilab, if the user is providing \t as separator, transform it to a real
           tab. Example: read_csv(filename,"\t");
        */
        strcpy(separator, "\t");
    }


    filename = csv_getArgumentAsString(pvApiCtx, 1, fname, &iErr);
    if (iErr)
    {
        freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
        return 0;
    }

    result = csvRead(filename, separator, decimal, (const char**)toreplace, nbElementsToReplace * 2, regexp, header);
    freeVar(NULL, &separator, &decimal, NULL, NULL, &toreplace, nbElementsToReplace, &regexp);

    if (result)
    {
        switch (result->err)
        {
            case CSV_READ_REGEXP_ERROR:
            {
                Scierror(999, _("%s: Wrong value for input argument #%d.\n"), fname, 6);
            }
            break;

            case CSV_READ_SEPARATOR_DECIMAL_EQUAL:
            {
                Scierror(999, _("%s: separator and decimal must have different values.\n"), fname);
            }
            break;

            case CSV_READ_NO_ERROR:
            {
                if (strcmp(conversion, CONVTOSTR) == 0)
                {
                    if (haveRange)
                    {
                        int newM = 0;
                        int newN = 0;

                        char **pStrRange = getRangeAsString((const char**)result->pstrValues, result->m, result->n, iRange, &newM, &newN);
                        if (pStrRange)
                        {
                            sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, newM, newN, pStrRange);
                            freeArrayOfString(pStrRange, newM * newN);
                        }
                        else
                        {
                            if ((newM == 0) || (newN == 0))
                            {
                                Scierror(999, _("%s: Range row or/and column left indice(s) out of bounds.\n"), fname);
                            }
                            else
                            {
                                Scierror(999, _("%s: Memory allocation error.\n"), fname);
                            }

                            freeCsvResult(result);
                            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
                            return 0;
                        }
                    }
                    else
                    {
                        sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, result->m, result->n, result->pstrValues);
                    }
                }
                else /* to double */
                {
                    stringToComplexError ierr = STRINGTOCOMPLEX_ERROR;
                    complexArray *ptrComplexArray = stringsToComplexArray((const char**)result->pstrValues, result->m * result->n, decimal, TRUE, &ierr);

                    if (ptrComplexArray == NULL)
                    {
                        freeCsvResult(result);
                        if (ierr == STRINGTOCOMPLEX_ERROR)
                        {
                            Scierror(999, _("%s: can not convert data.\n"), fname);
                        }
                        else
                        {
                            Scierror(999, _("%s: Memory allocation error.\n"), fname);
                        }

                        freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
                        return 0;
                    }

                    switch (ierr)
                    {
                        case STRINGTOCOMPLEX_NOT_A_NUMBER:
                        case STRINGTOCOMPLEX_NO_ERROR:
                        {
                            if (haveRange)
                            {
                                int newM = 0;
                                int newN = 0;
                                complexArray *complexRange = getRangeAsComplexArray(ptrComplexArray, result->m, result->n, iRange, &newM, &newN);
                                if (complexRange)
                                {
                                    if (complexRange->isComplex)
                                    {
                                        sciErr = createComplexMatrixOfDouble(pvApiCtx, Rhs + 1, newM, newN, ptrComplexArray->realPart, ptrComplexArray->imagPart);
                                    }
                                    else
                                    {
                                        sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, newM, newN, complexRange->realPart);
                                    }
                                    freeComplexArray(complexRange);
                                    complexRange = NULL;
                                }
                                else
                                {
                                    if ((newM == 0) || (newN == 0))
                                    {
                                        Scierror(999, _("%s: Range row or/and column left indice(s) out of bounds.\n"), fname);
                                    }
                                    else
                                    {
                                        Scierror(999, _("%s: Memory allocation error.\n"), fname);
                                    }

                                    freeCsvResult(result);
                                    freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
                                    return 0;
                                }
                            }
                            else
                            {
                                if (ptrComplexArray->isComplex)
                                {
                                    sciErr = createComplexMatrixOfDouble(pvApiCtx, Rhs + 1, result->m, result->n, ptrComplexArray->realPart, ptrComplexArray->imagPart);
                                }
                                else
                                {
                                    sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, result->m, result->n, ptrComplexArray->realPart);
                                }
                                freeComplexArray(ptrComplexArray);
                                ptrComplexArray = NULL;
                            }
                        }
                        break;

                        case STRINGTOCOMPLEX_MEMORY_ALLOCATION:
                        {
                            Scierror(999, _("%s: Memory allocation error.\n"), fname);
                            freeCsvResult(result);
                            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
                            return 0;
                        }
                        default:
                        case STRINGTOCOMPLEX_ERROR:
                        {
                            Scierror(999, _("%s: can not convert data.\n"), fname);
                            freeCsvResult(result);
                            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
                            return 0;
                        }
                    }
                }

                if (sciErr.iErr)
                {
                    Scierror(999, _("%s: Memory allocation error.\n"), fname);
                    freeCsvResult(result);
                    freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
                    return 0;
                }
                else
                {
                    LhsVar(1) = Rhs + 1;

                    if (Lhs == 2)
                    {
                        if (haveRegexp == 0)
                        {
                            char **emptyStringMatrix = NULL;
                            emptyStringMatrix = (char**) malloc(sizeof(char*));
                            emptyStringMatrix[0] = "";
                            sciErr = createMatrixOfString(pvApiCtx, Rhs + 2, 1, 1, emptyStringMatrix);
                            free(emptyStringMatrix);
                        }
                        else
                        {
                            if (result->nbComments > 0)
                            {
                               sciErr = createMatrixOfString(pvApiCtx, Rhs + 2, result->nbComments, 1, result->pstrComments);
                            }
                            else
                            {
                               iErrEmpty = createEmptyMatrix(pvApiCtx, Rhs+2);
                               sciErr.iErr = iErrEmpty;
                            }
                        }
                        if (sciErr.iErr)
                        {
                            Scierror(999, _("%s: Memory allocation error.\n"), fname);
                            freeCsvResult(result);
                            freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);
                            return 0;
                        }
                        LhsVar(2) = Rhs + 2;
                    }
                    PutLhsVar();
                }
            }
            break;

            case CSV_READ_FILE_NOT_EXIST:
            {
                Scierror(999, _("%s: %s does not exist.\n"), fname, filename);
            }
            break;

            case CSV_READ_MOPEN_ERROR:
            {
                Scierror(999, _("%s: can not open file %s.\n"), fname, filename);
            }
            break;

            case CSV_READ_MEMORY_ALLOCATION:
            {
                Scierror(999, _("%s: Memory allocation error.\n"), fname);
            }
            break;

            case CSV_READ_COLUMNS_ERROR:
            {
                Scierror(999, _("%s: can not read file %s: Error in the column structure\n"), fname, filename);
            }
            break;

            case CSV_READ_READLINES_ERROR:
            case CSV_READ_ERROR:
            {
                Scierror(999, _("%s: can not read file %s.\n"), fname, filename);
            }
            break;
        }
    }
    else
    {
        Scierror(999, _("%s: Memory allocation error.\n"), fname);
    }

    freeCsvResult(result);

    freeVar(&filename, &separator, &decimal, &conversion, &iRange, &toreplace, nbElementsToReplace, &regexp);

    return 0;
}