<commit_before>//******************************************************************************
// parser.c
//
// Converts a string expression into an expression tree. The following function
// is implemented:
//
//     int Parse(const char*, ExprTree*&)
//
//******************************************************************************

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "condor_exprtype.h"
#include "condor_ast.h"
#include "condor_scanner.h"

static	Token*	nextToken = NULL;
static	int		alreadyRead;

extern	void		Scanner(char*&, Token&);

int ParseExpr(char*& s, ExprTree*&, int&);

static	char*	StrCpy(char* str)
{
	char*	tmpStr = new char[strlen(str)+1];

	strcpy(tmpStr, str);
	return tmpStr;
}

////////////////////////////////////////////////////////////////////////////////
// ReadToken() reads in a token to the global variable for parse_... functions
// to use. Once a token is read by this function, it can not be looked at again.
////////////////////////////////////////////////////////////////////////////////
Token* ReadToken(char*& s)
{
    if(alreadyRead == TRUE)
    {
		nextToken = new Token;
        Scanner(s, *nextToken);
    }
    alreadyRead = TRUE;
    return(nextToken);
}

////////////////////////////////////////////////////////////////////////////////
// LookToken 'look at' a token without 'read' it, so that the next token that's
// read in is the same token. A token can be looked at for many times.
////////////////////////////////////////////////////////////////////////////////
Token* LookToken(char*& s)
{
    if(alreadyRead == TRUE)
    {
		nextToken = new Token;
        Scanner(s, *nextToken);
    }
    alreadyRead = FALSE;
    return(nextToken);
}

////////////////////////////////////////////////////////////////////////////////
// Match() reads in a token, see if its type matches the argument t. If it does,
// then return TRUE; Otherwise return FALSE.
////////////////////////////////////////////////////////////////////////////////
int Match(LexemeType t, char*& s, int& count)
{
    Token*	token;

    token = ReadToken(s);
    count = count + token->length;
    if(t == token->type)
    {
		delete token;
        return TRUE;
    }
	delete token;
    return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
// intermediate parse functions.
///////////////////////////////////////////////////////////////////////////////

int ParseFactor(char*& s, ExprTree*& newTree, int& count)
{
    Token*		t = LookToken(s);	// next token

    switch(t->type)
    {
        case LX_VARIABLE :

            t = ReadToken(s);
            newTree = new Variable(StrCpy(t->strVal));
    		count = count + t->length;
			delete t;
            break;

        case LX_INTEGER :

            t = ReadToken(s);
            newTree = new Integer(t->intVal);
    		count = count + t->length;
			delete t;
            break;

        case LX_FLOAT :

            t = ReadToken(s);
            newTree = new Float(t->floatVal);
    		count = count + t->length;
			delete t;
            break;

        case LX_STRING :

            t = ReadToken(s);
            newTree = new String(StrCpy(t->strVal));
    		count = count + t->length;
			delete t;
            break;

        case LX_BOOL :

            t = ReadToken(s);
            newTree = new Boolean(t->intVal);
    		count = count + t->length;
			delete t;
            break;

        case LX_NULL :

            t = ReadToken(s);
            newTree = new Null;
    		count = count + t->length;
			delete t;
            break;

        case LX_LPAREN :

            Match(LX_LPAREN, s, count);
            if(ParseExpr(s, newTree, count))
			{
                if(!Match(LX_RPAREN, s, count))
				{
					return FALSE;
				}
			}
			else
			{
				return FALSE;
			}
			return TRUE;

        case LX_SUB :	// unary minus

            Match(LX_SUB, s, count);
            t = ReadToken(s);
            if(t->type == LX_INTEGER)
			{
				newTree = new Integer(-t->intVal);
			}
			else if(t->type == LX_FLOAT)
			{
				newTree = new Float(-t->floatVal);
			}
    		count = count + t->length;
			delete t;
            break;

        default :

			newTree = new Error;
			return FALSE;
    }

    return TRUE;
}

int ParseX4(ExprTree* lArg, char*& s, ExprTree*& newTree, int& count)
{
    Token*			t = LookToken(s);	// next token
    ExprTree*		subTree;
    ExprTree*		rArg;

    switch(t->type)
    {
        case LX_MULT:

            Match(LX_MULT, s, count);
            if(ParseFactor(s, rArg, count))
			{
                subTree = new MultOp(lArg, rArg);
			}
			else
			{
                newTree = new MultOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_DIV :

            Match(LX_DIV, s, count);
            if(ParseFactor(s, rArg, count))
			{
                subTree = new DivOp(lArg, rArg);
			}
			else
			{
                newTree = new DivOp(lArg, rArg);
				return FALSE;
			}
            break;

        default :

			newTree = lArg;
            return TRUE;
    }

    return ParseX4(subTree, s, newTree, count);
}

int ParseMultOp(char*& s, ExprTree*& newTree, int& count)
{
    ExprTree*	lArg;

    if(ParseFactor(s, lArg, count))
    {
		return ParseX4(lArg, s, newTree, count);
    }
    newTree = lArg;
    return FALSE;
}

int ParseX3(ExprTree* lArg, char*& s, ExprTree*& newTree, int& count)
{
    Token*			t = LookToken(s);
    ExprTree*		subTree;
    ExprTree*		rArg;

    switch(t->type)
    {
        case LX_ADD :

            Match(LX_ADD, s, count);
            if(ParseMultOp(s, rArg, count))
			{
                subTree = new AddOp(lArg, rArg);
			}
			else
			{
                newTree = new AddOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_SUB :

            Match(LX_SUB, s, count);
            if(ParseMultOp(s, rArg, count))
			{
                subTree = new SubOp(lArg, rArg);
			}
			else
			{
                newTree = new SubOp(lArg, rArg);
				return FALSE;
			}
            break;

       default :

			newTree = lArg;
            return TRUE;
    }

    return ParseX3(subTree, s, newTree, count);
}

int ParseAddOp(char*& s, ExprTree*& newTree, int& count)
{
    Token*		t;
    ExprTree*	lArg;
    char*		tmp;

    if(ParseMultOp(s, lArg, count))
    {
        return ParseX3(lArg, s, newTree, count);
    }
    newTree = lArg;
    return FALSE;

    t = LookToken(s);
    if(t->type == LX_VARIABLE)
    {
		tmp = t->strVal;
		if(!strcmp(tmp, "K") || !strcmp(tmp, "k"))
		{
			ReadToken(s);
			delete t;
			newTree->unit = 'k';
		}
		if(!strcmp(tmp, "M") || !strcmp(tmp, "m"))
		{
			ReadToken(s);
			delete t;
		}
    }

    return TRUE;
}

int ParseX2(ExprTree* lArg, char*& s, ExprTree*& newTree, int& count)
{
    Token*		t = LookToken(s);
    ExprTree*	subTree;
    ExprTree*	rArg;

    switch(t->type)
    {
        case LX_EQ :

            Match(LX_EQ, s, count);
            if(ParseAddOp(s, rArg, count))
			{
                subTree = new EqOp(lArg, rArg);
			}
			else
			{
                newTree = new EqOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_NEQ :

            Match(LX_NEQ, s, count);
            if(ParseAddOp(s, rArg, count))
			{
                subTree = new NeqOp(lArg, rArg);
			}
			else
			{
                newTree = new NeqOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_LT:

            Match(LX_LT, s, count);
            if(ParseAddOp(s, rArg, count))
			{
				subTree = new LtOp(lArg, rArg);
			}
			else
			{
				newTree = new LtOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_LE :

            Match(LX_LE, s, count);
            if(ParseAddOp(s, rArg, count))
			{
                subTree = new LeOp(lArg, rArg);
			}
			else
			{
                newTree = new LeOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_GT:

            Match(LX_GT, s, count);
            if(ParseAddOp(s, rArg, count))
			{
                subTree = new GtOp(lArg, rArg);
			}
			else
			{
                newTree = new GtOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_GE :

            Match(LX_GE, s, count);
            if(ParseAddOp(s, rArg, count))
			{
                subTree = new GeOp(lArg, rArg);
			}
			else
			{
                newTree = new GeOp(lArg, rArg);
				return FALSE;
			}
            break;

        default :

			newTree = lArg;
            return TRUE;
    }

    return ParseX2(subTree, s, newTree, count);
}

int ParseSimpleExpr(char*& s, ExprTree*& newTree, int& count)
{
    ExprTree*	lArg;

    if(ParseAddOp(s, lArg, count))
    {
        return ParseX2(lArg, s, newTree, count);
    }
    newTree = lArg;
    return FALSE;
}

int ParseX1(ExprTree* lArg, char*& s, ExprTree*& newTree, int& count)
{
    Token*		t = LookToken(s);
    ExprTree*	subTree;
    ExprTree*	rArg;

    switch(t->type)
    {
        case LX_AND :

            Match(LX_AND, s, count);
            if(ParseSimpleExpr(s, rArg, count))
			{
                subTree = new AndOp(lArg, rArg);
			}
			else
			{
                newTree = new AndOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_OR :

            Match(LX_OR, s, count);
            if(ParseSimpleExpr(s, rArg, count))
			{
                subTree = new OrOp(lArg, rArg);
			}
			else
			{
                newTree = new OrOp(lArg, rArg);
				return FALSE;
			}
            break;

        default :

			newTree = lArg;
            return TRUE;
    }

    return ParseX1(subTree, s, newTree, count);
}

int ParseExpr(char*& s, ExprTree*& newTree, int& count)
{
    ExprTree*	lArg;

    if(ParseSimpleExpr(s, lArg, count))
    {
        return ParseX1(lArg, s, newTree, count);
    }
    newTree = lArg;
    return FALSE;
}

int ParseAssignExpr(char*& s, ExprTree*& newTree, int& count)
{
    Token*	t;
    ExprTree* 	lArg;
    ExprTree* 	rArg;

    if(ParseExpr(s, lArg, count))
    {
		t = LookToken(s);
		if(t->type == LX_ASSIGN)
		{
			Match(LX_ASSIGN, s, count);
			if(ParseExpr(s, rArg, count))
			{
				newTree = new AssignOp(lArg, rArg);
				t = LookToken(s);
				if(t->type == LX_EOF)
				{
					return TRUE;
				}
				return FALSE;
			}
			else
			{
				newTree = new AssignOp(lArg, rArg);
				return FALSE;
			}
		}
		else if(t->type == LX_EOF)
		{
			newTree = lArg;
			return TRUE;
		}
    }
    newTree = lArg;
    return FALSE;
}

int Parse(const char* s, ExprTree*& tree)
{
	char*		str = new char[strlen(s) + 1];
    char*		tmp = str;	// parsing indicator
    int			count = 0;	// count characters which has been read

	strcpy(str, s);
    alreadyRead = TRUE;
    if(ParseAssignExpr(tmp, tree, count))
    {
		delete nextToken;
		delete [] str;
		return 0;
    }
	delete nextToken;
	delete str;
    return count;
}

int Parse(char* s, ExprTree*& tree)
{
	return Parse((const char *)s, tree);
}
<commit_msg>Fixed another mis-matched memory free (where we need delete [] ).<commit_after>//******************************************************************************
// parser.c
//
// Converts a string expression into an expression tree. The following function
// is implemented:
//
//     int Parse(const char*, ExprTree*&)
//
//******************************************************************************

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "condor_exprtype.h"
#include "condor_ast.h"
#include "condor_scanner.h"

static	Token*	nextToken = NULL;
static	int		alreadyRead;

extern	void		Scanner(char*&, Token&);

int ParseExpr(char*& s, ExprTree*&, int&);

static	char*	StrCpy(char* str)
{
	char*	tmpStr = new char[strlen(str)+1];

	strcpy(tmpStr, str);
	return tmpStr;
}

////////////////////////////////////////////////////////////////////////////////
// ReadToken() reads in a token to the global variable for parse_... functions
// to use. Once a token is read by this function, it can not be looked at again.
////////////////////////////////////////////////////////////////////////////////
Token* ReadToken(char*& s)
{
    if(alreadyRead == TRUE)
    {
		nextToken = new Token;
        Scanner(s, *nextToken);
    }
    alreadyRead = TRUE;
    return(nextToken);
}

////////////////////////////////////////////////////////////////////////////////
// LookToken 'look at' a token without 'read' it, so that the next token that's
// read in is the same token. A token can be looked at for many times.
////////////////////////////////////////////////////////////////////////////////
Token* LookToken(char*& s)
{
    if(alreadyRead == TRUE)
    {
		nextToken = new Token;
        Scanner(s, *nextToken);
    }
    alreadyRead = FALSE;
    return(nextToken);
}

////////////////////////////////////////////////////////////////////////////////
// Match() reads in a token, see if its type matches the argument t. If it does,
// then return TRUE; Otherwise return FALSE.
////////////////////////////////////////////////////////////////////////////////
int Match(LexemeType t, char*& s, int& count)
{
    Token*	token;

    token = ReadToken(s);
    count = count + token->length;
    if(t == token->type)
    {
		delete token;
        return TRUE;
    }
	delete token;
    return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
// intermediate parse functions.
///////////////////////////////////////////////////////////////////////////////

int ParseFactor(char*& s, ExprTree*& newTree, int& count)
{
    Token*		t = LookToken(s);	// next token

    switch(t->type)
    {
        case LX_VARIABLE :

            t = ReadToken(s);
            newTree = new Variable(StrCpy(t->strVal));
    		count = count + t->length;
			delete t;
            break;

        case LX_INTEGER :

            t = ReadToken(s);
            newTree = new Integer(t->intVal);
    		count = count + t->length;
			delete t;
            break;

        case LX_FLOAT :

            t = ReadToken(s);
            newTree = new Float(t->floatVal);
    		count = count + t->length;
			delete t;
            break;

        case LX_STRING :

            t = ReadToken(s);
            newTree = new String(StrCpy(t->strVal));
    		count = count + t->length;
			delete t;
            break;

        case LX_BOOL :

            t = ReadToken(s);
            newTree = new Boolean(t->intVal);
    		count = count + t->length;
			delete t;
            break;

        case LX_NULL :

            t = ReadToken(s);
            newTree = new Null;
    		count = count + t->length;
			delete t;
            break;

        case LX_LPAREN :

            Match(LX_LPAREN, s, count);
            if(ParseExpr(s, newTree, count))
			{
                if(!Match(LX_RPAREN, s, count))
				{
					return FALSE;
				}
			}
			else
			{
				return FALSE;
			}
			return TRUE;

        case LX_SUB :	// unary minus

            Match(LX_SUB, s, count);
            t = ReadToken(s);
            if(t->type == LX_INTEGER)
			{
				newTree = new Integer(-t->intVal);
			}
			else if(t->type == LX_FLOAT)
			{
				newTree = new Float(-t->floatVal);
			}
    		count = count + t->length;
			delete t;
            break;

        default :

			newTree = new Error;
			return FALSE;
    }

    return TRUE;
}

int ParseX4(ExprTree* lArg, char*& s, ExprTree*& newTree, int& count)
{
    Token*			t = LookToken(s);	// next token
    ExprTree*		subTree;
    ExprTree*		rArg;

    switch(t->type)
    {
        case LX_MULT:

            Match(LX_MULT, s, count);
            if(ParseFactor(s, rArg, count))
			{
                subTree = new MultOp(lArg, rArg);
			}
			else
			{
                newTree = new MultOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_DIV :

            Match(LX_DIV, s, count);
            if(ParseFactor(s, rArg, count))
			{
                subTree = new DivOp(lArg, rArg);
			}
			else
			{
                newTree = new DivOp(lArg, rArg);
				return FALSE;
			}
            break;

        default :

			newTree = lArg;
            return TRUE;
    }

    return ParseX4(subTree, s, newTree, count);
}

int ParseMultOp(char*& s, ExprTree*& newTree, int& count)
{
    ExprTree*	lArg;

    if(ParseFactor(s, lArg, count))
    {
		return ParseX4(lArg, s, newTree, count);
    }
    newTree = lArg;
    return FALSE;
}

int ParseX3(ExprTree* lArg, char*& s, ExprTree*& newTree, int& count)
{
    Token*			t = LookToken(s);
    ExprTree*		subTree;
    ExprTree*		rArg;

    switch(t->type)
    {
        case LX_ADD :

            Match(LX_ADD, s, count);
            if(ParseMultOp(s, rArg, count))
			{
                subTree = new AddOp(lArg, rArg);
			}
			else
			{
                newTree = new AddOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_SUB :

            Match(LX_SUB, s, count);
            if(ParseMultOp(s, rArg, count))
			{
                subTree = new SubOp(lArg, rArg);
			}
			else
			{
                newTree = new SubOp(lArg, rArg);
				return FALSE;
			}
            break;

       default :

			newTree = lArg;
            return TRUE;
    }

    return ParseX3(subTree, s, newTree, count);
}

int ParseAddOp(char*& s, ExprTree*& newTree, int& count)
{
    Token*		t;
    ExprTree*	lArg;
    char*		tmp;

    if(ParseMultOp(s, lArg, count))
    {
        return ParseX3(lArg, s, newTree, count);
    }
    newTree = lArg;
    return FALSE;

    t = LookToken(s);
    if(t->type == LX_VARIABLE)
    {
		tmp = t->strVal;
		if(!strcmp(tmp, "K") || !strcmp(tmp, "k"))
		{
			ReadToken(s);
			delete t;
			newTree->unit = 'k';
		}
		if(!strcmp(tmp, "M") || !strcmp(tmp, "m"))
		{
			ReadToken(s);
			delete t;
		}
    }

    return TRUE;
}

int ParseX2(ExprTree* lArg, char*& s, ExprTree*& newTree, int& count)
{
    Token*		t = LookToken(s);
    ExprTree*	subTree;
    ExprTree*	rArg;

    switch(t->type)
    {
        case LX_EQ :

            Match(LX_EQ, s, count);
            if(ParseAddOp(s, rArg, count))
			{
                subTree = new EqOp(lArg, rArg);
			}
			else
			{
                newTree = new EqOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_NEQ :

            Match(LX_NEQ, s, count);
            if(ParseAddOp(s, rArg, count))
			{
                subTree = new NeqOp(lArg, rArg);
			}
			else
			{
                newTree = new NeqOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_LT:

            Match(LX_LT, s, count);
            if(ParseAddOp(s, rArg, count))
			{
				subTree = new LtOp(lArg, rArg);
			}
			else
			{
				newTree = new LtOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_LE :

            Match(LX_LE, s, count);
            if(ParseAddOp(s, rArg, count))
			{
                subTree = new LeOp(lArg, rArg);
			}
			else
			{
                newTree = new LeOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_GT:

            Match(LX_GT, s, count);
            if(ParseAddOp(s, rArg, count))
			{
                subTree = new GtOp(lArg, rArg);
			}
			else
			{
                newTree = new GtOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_GE :

            Match(LX_GE, s, count);
            if(ParseAddOp(s, rArg, count))
			{
                subTree = new GeOp(lArg, rArg);
			}
			else
			{
                newTree = new GeOp(lArg, rArg);
				return FALSE;
			}
            break;

        default :

			newTree = lArg;
            return TRUE;
    }

    return ParseX2(subTree, s, newTree, count);
}

int ParseSimpleExpr(char*& s, ExprTree*& newTree, int& count)
{
    ExprTree*	lArg;

    if(ParseAddOp(s, lArg, count))
    {
        return ParseX2(lArg, s, newTree, count);
    }
    newTree = lArg;
    return FALSE;
}

int ParseX1(ExprTree* lArg, char*& s, ExprTree*& newTree, int& count)
{
    Token*		t = LookToken(s);
    ExprTree*	subTree;
    ExprTree*	rArg;

    switch(t->type)
    {
        case LX_AND :

            Match(LX_AND, s, count);
            if(ParseSimpleExpr(s, rArg, count))
			{
                subTree = new AndOp(lArg, rArg);
			}
			else
			{
                newTree = new AndOp(lArg, rArg);
				return FALSE;
			}
            break;

        case LX_OR :

            Match(LX_OR, s, count);
            if(ParseSimpleExpr(s, rArg, count))
			{
                subTree = new OrOp(lArg, rArg);
			}
			else
			{
                newTree = new OrOp(lArg, rArg);
				return FALSE;
			}
            break;

        default :

			newTree = lArg;
            return TRUE;
    }

    return ParseX1(subTree, s, newTree, count);
}

int ParseExpr(char*& s, ExprTree*& newTree, int& count)
{
    ExprTree*	lArg;

    if(ParseSimpleExpr(s, lArg, count))
    {
        return ParseX1(lArg, s, newTree, count);
    }
    newTree = lArg;
    return FALSE;
}

int ParseAssignExpr(char*& s, ExprTree*& newTree, int& count)
{
    Token*	t;
    ExprTree* 	lArg;
    ExprTree* 	rArg;

    if(ParseExpr(s, lArg, count))
    {
		t = LookToken(s);
		if(t->type == LX_ASSIGN)
		{
			Match(LX_ASSIGN, s, count);
			if(ParseExpr(s, rArg, count))
			{
				newTree = new AssignOp(lArg, rArg);
				t = LookToken(s);
				if(t->type == LX_EOF)
				{
					return TRUE;
				}
				return FALSE;
			}
			else
			{
				newTree = new AssignOp(lArg, rArg);
				return FALSE;
			}
		}
		else if(t->type == LX_EOF)
		{
			newTree = lArg;
			return TRUE;
		}
    }
    newTree = lArg;
    return FALSE;
}

int Parse(const char* s, ExprTree*& tree)
{
	char*		str = new char[strlen(s) + 1];
    char*		tmp = str;	// parsing indicator
    int			count = 0;	// count characters which has been read

	strcpy(str, s);
    alreadyRead = TRUE;
    if(ParseAssignExpr(tmp, tree, count))
    {
		delete nextToken;
		delete [] str;
		return 0;
    }
	delete nextToken;
	delete [] str;
    return count;
}

int Parse(char* s, ExprTree*& tree)
{
	return Parse((const char *)s, tree);
}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_MAPPING_EXTERNALINTERPOLATIONMAPPING_INL
#define SOFA_COMPONENT_MAPPING_EXTERNALINTERPOLATIONMAPPING_INL

#include "ExternalInterpolationMapping.h"
#include <sofa/core/componentmodel/topology/BaseMeshTopology.h>

namespace sofa
{

namespace component
{

namespace mapping
{

template <class BaseMapping>
ExternalInterpolationMapping<BaseMapping>::ExternalInterpolationMapping(In* from, Out* to)
    : Inherit(from, to)
    , f_interpolationIndices( initData(&f_interpolationIndices, "InterpolationIndices", "Table that provides interpolation Indices"))
    , f_interpolationValues( initData(&f_interpolationValues, "InterpolationValues", "Table that provides interpolation Values"))
    , doNotMap(false)
{
}

template <class BaseMapping>
ExternalInterpolationMapping<BaseMapping>::~ExternalInterpolationMapping()
{
}

// Handle topological changes
template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::handleTopologyChange(core::componentmodel::topology::Topology* /*t*/)
{
    /*
     core::componentmodel::topology::BaseMeshTopology* topoFrom = this->fromModel->getContext()->getMeshTopology();
     if (t != topoFrom) return;
     std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin=topoFrom->firstChange();
     std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd=topoFrom->lastChange();
     f_indices.beginEdit()->handleTopologyEvents(itBegin,itEnd,this->fromModel->getX()->size());
     f_indices.endEdit();
    */
}

template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::init()
{
    // verification of the input table:

    const sofa::helper::vector<sofa::helper::vector< unsigned int > > table_indices = f_interpolationIndices.getValue();
    const sofa::helper::vector<sofa::helper::vector< Real > > table_values = f_interpolationValues.getValue();

    if(table_indices.size() != table_values.size())
    {
        serr<<"WARNING interpolationIndices and interpolationValues do not have the same size ! DoNotMap activated !!"<<sendl;
        doNotMap = true;

        for (unsigned int i=0; i<table_indices.size(); i++)
        {
            if (table_indices[i].size() != table_values[i].size() )
            {
                serr<<"WARNING interpolationIndices and interpolationValues do not have the same size for point "<< i <<" ! DoNotMap activated !!"<<sendl;
                doNotMap = true;
            }
            if (table_indices[i].size() == 0 )
            {
                serr<<"WARNING  no interpolation for point "<< i <<" ! DoNotMap activated !!"<<sendl;
                doNotMap = true;
            }

        }
    }

    this->Inherit::init();
}

template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
{
    if(doNotMap)
        return;

    const sofa::helper::vector<sofa::helper::vector< unsigned int > > table_indices = f_interpolationIndices.getValue();
    const sofa::helper::vector<sofa::helper::vector< Real > > table_values = f_interpolationValues.getValue();

    out.resize(table_indices.size());
    for(unsigned int i = 0; i < out.size(); ++i)
    {
        out[i] = in[ table_indices[i][0] ]  * table_values[i][0];
        for(unsigned int j = 1; j < table_indices[i].size(); j++)
        {
            out[i] += in[ table_indices[i][j] ]  * table_values[i][j];
        }
    }

}

template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
{
    if(doNotMap)
        return;

    const sofa::helper::vector<sofa::helper::vector< unsigned int > > table_indices = f_interpolationIndices.getValue();
    const sofa::helper::vector<sofa::helper::vector< Real > > table_values = f_interpolationValues.getValue();

    out.resize(table_indices.size());
    for(unsigned int i = 0; i < out.size(); ++i)
    {
        out[i] = in[ table_indices[i][0] ] * table_values[i][0];
        for(unsigned int j = 1; j < table_indices[i].size(); j++)
        {
            out[i] += in[ table_indices[i][j] ] * table_values[i][j];
        }

    }
}

template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
{
    if(doNotMap)
        return;

    const sofa::helper::vector<sofa::helper::vector< unsigned int > > table_indices = f_interpolationIndices.getValue();
    const sofa::helper::vector<sofa::helper::vector< Real > > table_values = f_interpolationValues.getValue();

    for(unsigned int i = 0; i < in.size(); ++i)
    {
        for(unsigned int j = 0; j < table_indices[i].size(); j++)
        {
            out[table_indices[i][j]] += in[ i ] * table_values[i][j];
        }

    }

}

template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
{
    if(doNotMap)
        return;

    const sofa::helper::vector<sofa::helper::vector< unsigned int > > table_indices = f_interpolationIndices.getValue();
    const sofa::helper::vector<sofa::helper::vector< Real > > table_values = f_interpolationValues.getValue();

    int offset = out.size();
    out.resize(offset+in.size());

    for(unsigned int i = 0; i < in.size(); ++i)
    {
        OutConstraintIterator itOut;
        std::pair< OutConstraintIterator, OutConstraintIterator > iter=in[i].data();

        for (itOut=iter.first; itOut!=iter.second; itOut++)
        {
            unsigned int indexIn = itOut->first;
            OutDeriv data = (OutDeriv) itOut->second;

            for(unsigned int j = 0; j < table_indices[i].size(); j++)
            {

                out[i+offset].add( table_indices[indexIn][j] , data*table_values[indexIn][j] );
            }
        }
    }

}

} // namespace mapping

} // namespace component

} // namespace sofa

#endif
<commit_msg>r6991/sofa-dev : UPDATE : restructure FEM<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_MAPPING_EXTERNALINTERPOLATIONMAPPING_INL
#define SOFA_COMPONENT_MAPPING_EXTERNALINTERPOLATIONMAPPING_INL

#include "ExternalInterpolationMapping.h"
#include <sofa/core/componentmodel/topology/BaseMeshTopology.h>

namespace sofa
{

namespace component
{

namespace mapping
{

template <class BaseMapping>
ExternalInterpolationMapping<BaseMapping>::ExternalInterpolationMapping(In* from, Out* to)
    : Inherit(from, to)
    , f_interpolationIndices( initData(&f_interpolationIndices, "InterpolationIndices", "Table that provides interpolation Indices"))
    , f_interpolationValues( initData(&f_interpolationValues, "InterpolationValues", "Table that provides interpolation Values"))
    , doNotMap(false)
{
}

template <class BaseMapping>
ExternalInterpolationMapping<BaseMapping>::~ExternalInterpolationMapping()
{
}

// Handle topological changes
template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::handleTopologyChange(core::componentmodel::topology::Topology* /*t*/)
{
    /*
     core::componentmodel::topology::BaseMeshTopology* topoFrom = this->fromModel->getContext()->getMeshTopology();
     if (t != topoFrom) return;
     std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itBegin=topoFrom->firstChange();
     std::list<const core::componentmodel::topology::TopologyChange *>::const_iterator itEnd=topoFrom->lastChange();
     f_indices.beginEdit()->handleTopologyEvents(itBegin,itEnd,this->fromModel->getX()->size());
     f_indices.endEdit();
    */
}

template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::init()
{
    // verification of the input table:

    const sofa::helper::vector<sofa::helper::vector< unsigned int > > table_indices = f_interpolationIndices.getValue();
    const sofa::helper::vector<sofa::helper::vector< Real > > table_values = f_interpolationValues.getValue();

    if(table_indices.size() != table_values.size())
    {
        serr<<"WARNING interpolationIndices and interpolationValues do not have the same size ! DoNotMap activated !!"<<sendl;
        doNotMap = true;

        for (unsigned int i=0; i<table_indices.size(); i++)
        {
            if (table_indices[i].size() != table_values[i].size() )
            {
                serr<<"WARNING interpolationIndices and interpolationValues do not have the same size for point "<< i <<" ! DoNotMap activated !!"<<sendl;
                doNotMap = true;
            }
            if (table_indices[i].size() == 0 )
            {
                serr<<"WARNING  no interpolation for point "<< i <<" ! DoNotMap activated !!"<<sendl;
                doNotMap = true;
            }

        }
    }

    this->Inherit::init();
}

template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::apply( typename Out::VecCoord& out, const typename In::VecCoord& in )
{
    if(doNotMap)
        return;

    const sofa::helper::vector<sofa::helper::vector< unsigned int > > table_indices = f_interpolationIndices.getValue();
    const sofa::helper::vector<sofa::helper::vector< Real > > table_values = f_interpolationValues.getValue();

    out.resize(table_indices.size());
    for(unsigned int i = 0; i < out.size(); ++i)
    {
        out[i] = in[ table_indices[i][0] ]  * table_values[i][0];
        for(unsigned int j = 1; j < table_indices[i].size(); j++)
        {
            out[i] += in[ table_indices[i][j] ]  * table_values[i][j];
        }
    }
}

template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::applyJ( typename Out::VecDeriv& out, const typename In::VecDeriv& in )
{
    if(doNotMap)
        return;

    const sofa::helper::vector<sofa::helper::vector< unsigned int > > table_indices = f_interpolationIndices.getValue();
    const sofa::helper::vector<sofa::helper::vector< Real > > table_values = f_interpolationValues.getValue();

    out.resize(table_indices.size());
    for(unsigned int i = 0; i < out.size(); ++i)
    {
        out[i] = in[ table_indices[i][0] ] * table_values[i][0];
        for(unsigned int j = 1; j < table_indices[i].size(); j++)
        {
            out[i] += in[ table_indices[i][j] ] * table_values[i][j];
        }

    }
}

template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::applyJT( typename In::VecDeriv& out, const typename Out::VecDeriv& in )
{
    if(doNotMap)
        return;

    const sofa::helper::vector<sofa::helper::vector< unsigned int > > table_indices = f_interpolationIndices.getValue();
    const sofa::helper::vector<sofa::helper::vector< Real > > table_values = f_interpolationValues.getValue();

    for(unsigned int i = 0; i < in.size(); ++i)
    {
        for(unsigned int j = 0; j < table_indices[i].size(); j++)
        {
            out[table_indices[i][j]] += in[ i ] * table_values[i][j];
        }

    }

}

template <class BaseMapping>
void ExternalInterpolationMapping<BaseMapping>::applyJT( typename In::VecConst& out, const typename Out::VecConst& in )
{
    if(doNotMap)
        return;

    const sofa::helper::vector<sofa::helper::vector< unsigned int > > table_indices = f_interpolationIndices.getValue();
    const sofa::helper::vector<sofa::helper::vector< Real > > table_values = f_interpolationValues.getValue();

    int offset = out.size();
    out.resize(offset+in.size());

    for(unsigned int i = 0; i < in.size(); ++i)
    {
        OutConstraintIterator itOut;
        std::pair< OutConstraintIterator, OutConstraintIterator > iter=in[i].data();

        for (itOut=iter.first; itOut!=iter.second; itOut++)
        {
            unsigned int indexIn = itOut->first;
            OutDeriv data = (OutDeriv) itOut->second;

            for(unsigned int j = 0; j < table_indices[i].size(); j++)
            {

                out[i+offset].add( table_indices[indexIn][j] , data*table_values[indexIn][j] );
            }
        }
    }

}

} // namespace mapping

} // namespace component

} // namespace sofa

#endif
<|endoftext|>


<commit_before>/*

Copyright (c) 2013,2014, Project OSRM, Dennis Luxen, others
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef RANGE_H
#define RANGE_H

#include <type_traits>

namespace osrm
{

template <typename Integer> class range
{
  private:
    Integer last;
    Integer iter;

  public:
    range(Integer start, Integer end) : last(end), iter(start)
    {
        static_assert(std::is_integral<Integer>::value, "range type must be integral");
    }

    // Iterable functions
    const range &begin() const { return *this; }
    const range &end() const { return *this; }
    Integer front() const { return iter; }
    Integer back() const { return last - 1; }

    // Iterator functions
    bool operator!=(const range &) const { return iter < last; }
    void operator++() { ++iter; }
    Integer operator*() const { return iter; }
};

// convenience function to construct an integer range with type deduction
template <typename Integer> range<Integer> irange(Integer first, Integer last)
{
    return range<Integer>(first, last);
}
}

#endif // RANGE_H
<commit_msg>reformat code<commit_after>/*

Copyright (c) 2013,2014, Project OSRM, Dennis Luxen, others
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef INTEGER_RANGE_HPP
#define INTEGER_RANGE_HPP

#include <type_traits>

namespace osrm
{

template <typename Integer> class range
{
  private:
    Integer last;
    Integer iter;

  public:
    range(Integer start, Integer end) : last(end), iter(start)
    {
        static_assert(std::is_integral<Integer>::value, "range type must be integral");
    }

    // Iterable functions
    const range &begin() const { return *this; }
    const range &end() const { return *this; }
    Integer front() const { return iter; }
    Integer back() const { return last - 1; }

    // Iterator functions
    bool operator!=(const range &) const { return iter < last; }
    void operator++() { ++iter; }
    Integer operator*() const { return iter; }
};

// convenience function to construct an integer range with type deduction
template <typename Integer>
range<Integer> irange(const Integer first,
                      const Integer last,
                      typename std::enable_if<std::is_integral<Integer>::value>::type * = 0)
{
    return range<Integer>(first, last);
}
}

#endif // INTEGER_RANGE_HPP
<|endoftext|>


<commit_before>#include "args.hpp"
#include "evaluator.hpp"
#include "frameset.hpp"
#include "report.hpp"
#include "video.hpp"
#include "window.hpp"
#include <fmo/explorer.hpp>
#include <fmo/processing.hpp>
#include <fmo/stats.hpp>
#include <iostream>

struct Status {
    Args args;           ///< user settings
    Window window;       ///< GUI handle
    Results results;     ///< evaluation results
    Results baseline;    ///< previous evaluation results
    fmo::Timer timer;    ///< timer for the whole run
    bool paused = false; ///< playback paused
    bool quit = false;   ///< exit application now
    bool reload = false; ///< laod the same video again

    Status(int argc, char** argv) : args(argc, argv) {}
};

void processVideo(Status& s, size_t inputNum);

int main(int argc, char** argv) try {
    Status s{argc, argv};

    if (!s.args.baseline.empty()) { s.baseline.load(s.args.baseline); }
    if (s.args.camera != -1) { s.args.inputs.emplace_back(); }

    for (size_t i = 0; !s.quit && i < s.args.inputs.size(); i++) {
        try {
            do {
                s.reload = false;
                processVideo(s, i);
            } while (s.reload);
        } catch (std::exception& e) {
            std::cerr << "while playing '" << s.args.inputs.at(i) << "'\n";
            throw e;
        }
    }

    Report report(s.results, s.baseline, s.timer.toc<fmo::TimeUnit::SEC, float>());
    report.write(std::cout);
    if (!s.args.evalDir.empty()) { report.save(s.args.evalDir); }
} catch (std::exception& e) {
    std::cerr << "error: " << e.what() << '\n';
    std::cerr << "tip: use --help to see a list of available commands\n";
    return -1;
}

void processVideo(Status& s, size_t inputNum) {
    // open input
    auto input = (s.args.camera == -1) ? VideoInput::makeFromFile(s.args.inputs.at(inputNum))
                                       : VideoInput::makeFromCamera(s.args.camera);
    auto dims = input->dims();
    float fps = input->fps();
    std::string inputName = (s.args.camera == -1) ? extractFilename(s.args.inputs.at(inputNum))
                                                  : "camera " + std::to_string(s.args.camera);

    // open GT
    std::unique_ptr<Evaluator> evaluator;
    if (!s.args.gts.empty()) {
        evaluator =
            std::make_unique<Evaluator>(s.args.gts.at(inputNum), dims, s.results, s.baseline);
    }

    // open output
    std::unique_ptr<VideoOutput> output;
    if (!s.args.recordDir.empty()) {
        output = VideoOutput::makeInDirectory(s.args.recordDir, dims, fps);
    }

    // set speed
    if (s.args.camera == -1) {
        float waitSec = (s.args.wait != -1) ? (float(s.args.wait) / 1e3f) : (1.f / fps);
        s.window.setFrameTime(waitSec);
    }

    // setup caches
    fmo::Explorer::Config explorerCfg;
    explorerCfg.dims = dims;
    fmo::Explorer explorer{explorerCfg};
    fmo::Image gray{fmo::Format::GRAY, dims};
    fmo::Image vis{fmo::Format::BGR, dims};
    fmo::Explorer::Object object;

    for (int frameNum = 1; !s.quit && !s.reload; frameNum++) {
        // workaround: linux waits for 5 sec when there's no more frames
        if (evaluator) {
            if (frameNum > evaluator->numFrames()) break;
        }

        // read and write video
        auto frame = input->receiveFrame();
        if (frame.data() == nullptr) break;
        if (output) { output->sendFrame(frame); }

        // process
        fmo::convert(frame, gray, fmo::Format::GRAY);
        explorer.setInputSwap(gray);

        // evaluate
        explorer.getObject(object);
        EvalResult result;
        if (evaluator) {
            result = evaluator->evaluateFrame(object.points, frameNum);
            if (s.args.pauseFn && result.eval == Evaluation::FN) s.paused = true;
            if (s.args.pauseFp && result.eval == Evaluation::FP) s.paused = true;
            if (s.args.pauseRg && result.comp == Comparison::REGRESSION) s.paused = true;
            if (s.args.pauseIm && result.comp == Comparison::IMPROVEMENT) s.paused = true;
        }

        // pause when the sought-for frame number is encountered
        if (s.args.frame == frameNum) {
            s.args.frame = -1;
            s.paused = true;
        }

        // skip other steps if in headless mode or if seeking
        if ((s.args.frame != -1 || s.args.headless) && !s.paused) continue;

        // visualize
        fmo::copy(explorer.getDebugImage(), vis);
        s.window.print(inputName);
        s.window.print("frame: " + std::to_string(frameNum));
        if (evaluator) {
            s.window.print(result.str());
            drawPointsGt(object.points, evaluator->groundTruth(frameNum), vis);
            s.window.setTextColor(good(result.eval) ? Color{0x40, 0x80, 0x40}
                                                    : Color{0x40, 0x40, 0x80});
        } else {
            drawPoints(object.points, vis, Color{0xFF, 0x00, 0x00});
        }
        s.window.display(vis);

        // process keyboard input
        bool step = false;
        do {
            auto command = s.window.getCommand(s.paused);
            if (command == Command::PAUSE) s.paused = !s.paused;
            if (command == Command::STEP) step = true;
            if (command == Command::QUIT) s.quit = true;

            if (s.args.camera == -1) {
                if (command == Command::JUMP_BACKWARD) {
                    s.paused = false;
                    s.args.frame = std::max(1, frameNum - 10);
                    s.reload = true;
                }
                if (command == Command::JUMP_FORWARD) {
                    s.paused = false;
                    s.args.frame = frameNum + 10;
                }
            }
        } while (s.paused && !step && !s.quit);
    }
}
<commit_msg>Fix seeking interfering with pausing<commit_after>#include "args.hpp"
#include "evaluator.hpp"
#include "frameset.hpp"
#include "report.hpp"
#include "video.hpp"
#include "window.hpp"
#include <fmo/explorer.hpp>
#include <fmo/processing.hpp>
#include <fmo/stats.hpp>
#include <iostream>

struct Status {
    Args args;           ///< user settings
    Window window;       ///< GUI handle
    Results results;     ///< evaluation results
    Results baseline;    ///< previous evaluation results
    fmo::Timer timer;    ///< timer for the whole run
    bool paused = false; ///< playback paused
    bool quit = false;   ///< exit application now
    bool reload = false; ///< laod the same video again

    Status(int argc, char** argv) : args(argc, argv) {}
};

void processVideo(Status& s, size_t inputNum);

int main(int argc, char** argv) try {
    Status s{argc, argv};

    if (!s.args.baseline.empty()) { s.baseline.load(s.args.baseline); }
    if (s.args.camera != -1) { s.args.inputs.emplace_back(); }

    for (size_t i = 0; !s.quit && i < s.args.inputs.size(); i++) {
        try {
            do {
                s.reload = false;
                processVideo(s, i);
            } while (s.reload);
        } catch (std::exception& e) {
            std::cerr << "while playing '" << s.args.inputs.at(i) << "'\n";
            throw e;
        }
    }

    Report report(s.results, s.baseline, s.timer.toc<fmo::TimeUnit::SEC, float>());
    report.write(std::cout);
    if (!s.args.evalDir.empty()) { report.save(s.args.evalDir); }
} catch (std::exception& e) {
    std::cerr << "error: " << e.what() << '\n';
    std::cerr << "tip: use --help to see a list of available commands\n";
    return -1;
}

void processVideo(Status& s, size_t inputNum) {
    // open input
    auto input = (s.args.camera == -1) ? VideoInput::makeFromFile(s.args.inputs.at(inputNum))
                                       : VideoInput::makeFromCamera(s.args.camera);
    auto dims = input->dims();
    float fps = input->fps();
    std::string inputName = (s.args.camera == -1) ? extractFilename(s.args.inputs.at(inputNum))
                                                  : "camera " + std::to_string(s.args.camera);

    // open GT
    std::unique_ptr<Evaluator> evaluator;
    if (!s.args.gts.empty()) {
        evaluator =
            std::make_unique<Evaluator>(s.args.gts.at(inputNum), dims, s.results, s.baseline);
    }

    // open output
    std::unique_ptr<VideoOutput> output;
    if (!s.args.recordDir.empty()) {
        output = VideoOutput::makeInDirectory(s.args.recordDir, dims, fps);
    }

    // set speed
    if (s.args.camera == -1) {
        float waitSec = (s.args.wait != -1) ? (float(s.args.wait) / 1e3f) : (1.f / fps);
        s.window.setFrameTime(waitSec);
    }

    // setup caches
    fmo::Explorer::Config explorerCfg;
    explorerCfg.dims = dims;
    fmo::Explorer explorer{explorerCfg};
    fmo::Image gray{fmo::Format::GRAY, dims};
    fmo::Image vis{fmo::Format::BGR, dims};
    fmo::Explorer::Object object;

    for (int frameNum = 1; !s.quit && !s.reload; frameNum++) {
        // workaround: linux waits for 5 sec when there's no more frames
        if (evaluator) {
            if (frameNum > evaluator->numFrames()) break;
        }

        // read and write video
        auto frame = input->receiveFrame();
        if (frame.data() == nullptr) break;
        if (output) { output->sendFrame(frame); }

        // process
        fmo::convert(frame, gray, fmo::Format::GRAY);
        explorer.setInputSwap(gray);

        // evaluate
        explorer.getObject(object);
        EvalResult result;
        if (evaluator) {
            result = evaluator->evaluateFrame(object.points, frameNum);
            if (s.args.pauseFn && result.eval == Evaluation::FN) s.paused = true;
            if (s.args.pauseFp && result.eval == Evaluation::FP) s.paused = true;
            if (s.args.pauseRg && result.comp == Comparison::REGRESSION) s.paused = true;
            if (s.args.pauseIm && result.comp == Comparison::IMPROVEMENT) s.paused = true;
        }

        // pause when the sought-for frame number is encountered
        if (s.args.frame == frameNum) {
            s.args.frame = -1;
            s.paused = true;
        }

        // skip other steps if seeking
        if (s.args.frame != -1) continue;

        // skip other steps if in headless mode (but not paused)
        if (s.args.headless && !s.paused) continue;

        // visualize
        fmo::copy(explorer.getDebugImage(), vis);
        s.window.print(inputName);
        s.window.print("frame: " + std::to_string(frameNum));
        if (evaluator) {
            s.window.print(result.str());
            drawPointsGt(object.points, evaluator->groundTruth(frameNum), vis);
            s.window.setTextColor(good(result.eval) ? Color{0x40, 0x80, 0x40}
                                                    : Color{0x40, 0x40, 0x80});
        } else {
            drawPoints(object.points, vis, Color{0xFF, 0x00, 0x00});
        }
        s.window.display(vis);

        // process keyboard input
        bool step = false;
        do {
            auto command = s.window.getCommand(s.paused);
            if (command == Command::PAUSE) s.paused = !s.paused;
            if (command == Command::STEP) step = true;
            if (command == Command::QUIT) s.quit = true;

            if (s.args.camera == -1) {
                if (command == Command::JUMP_BACKWARD) {
                    s.paused = false;
                    s.args.frame = std::max(1, frameNum - 10);
                    s.reload = true;
                }
                if (command == Command::JUMP_FORWARD) {
                    s.paused = false;
                    s.args.frame = frameNum + 10;
                }
            }
        } while (s.paused && !step && !s.quit);
    }
}
<|endoftext|>


<commit_before>#include "randomlifetime.h"

#include <stdlib.h>

#include "particle.h"

RandomLifetime::RandomLifetime(float max, float min) :
  Initializer(),
  _min(min),
  _range(max - min) {
}

RandomLifetime::~RandomLifetime() {
}

void RandomLifetime::apply(Particle *p, Emitter *e) {
  p->lifetime = _min + (float)rand()/(float)RAND_MAX * _range;
}
<commit_msg>Refactoring<commit_after>#include "randomlifetime.h"

#include <stdlib.h>

#include "particle.h"

RandomLifetime::RandomLifetime(float max, float min) :
  Initializer(),
  _min(min),
  _range(max - min) {
}

RandomLifetime::~RandomLifetime() {
}

void RandomLifetime::apply(Particle *p, Emitter *e) {
  p->lifetime = _min + _range * (float)rand()/(float)RAND_MAX;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ftpcontentidentifier.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: abi $ $Date: 2002-10-29 12:43:13 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

/**************************************************************************
                                TODO
 **************************************************************************

 *************************************************************************/
#ifndef _FTP_FTPCONTENTIDENTIFIER_HXX_
#define _FTP_FTPCONTENTIDENTIFIER_HXX_

#include <vector>
#include <curl/curl.h>
#include <curl/easy.h>
#include <cppuhelper/weak.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <com/sun/star/ucb/XContentIdentifier.hpp>
#include <com/sun/star/lang/XTypeProvider.hpp>

#include "ftpdirp.hxx"
#include "ftpurl.hxx"

namespace ftp {

    class FTPContentProvider;

    class FTPContentIdentifier
        : public cppu::OWeakObject,
          public com::sun::star::lang::XTypeProvider,
          public com::sun::star::ucb::XContentIdentifier
    {
    public:

        FTPContentIdentifier(const rtl::OUString& ident);

        ~FTPContentIdentifier();

        // XInterface

        virtual com::sun::star::uno::Any SAL_CALL
        queryInterface( const com::sun::star::uno::Type& rType )
            throw( com::sun::star::uno::RuntimeException );

        virtual void SAL_CALL acquire( void ) throw();

        virtual void SAL_CALL release( void ) throw();

        // XTypeProvider

        virtual
        com::sun::star::uno::Sequence<com::sun::star::uno::Type> SAL_CALL
        getTypes(
        )
            throw(
                com::sun::star::uno::RuntimeException
            );

        virtual com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
        getImplementationId(
        )
            throw(
                com::sun::star::uno::RuntimeException
            );

        // XContentIdentifier

        virtual ::rtl::OUString SAL_CALL
        getContentIdentifier(
        )
            throw (
                com::sun::star::uno::RuntimeException
            );

        virtual ::rtl::OUString SAL_CALL
        getContentProviderScheme(
        )
            throw (
                ::com::sun::star::uno::RuntimeException
            );

    private:

        rtl::OUString m_ident;
    };

}

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.5.250); FILE MERGED 2005/09/05 18:45:07 rt 1.5.250.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ftpcontentidentifier.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 15:33:01 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

/**************************************************************************
                                TODO
 **************************************************************************

 *************************************************************************/
#ifndef _FTP_FTPCONTENTIDENTIFIER_HXX_
#define _FTP_FTPCONTENTIDENTIFIER_HXX_

#include <vector>
#include <curl/curl.h>
#include <curl/easy.h>
#include <cppuhelper/weak.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <com/sun/star/ucb/XContentIdentifier.hpp>
#include <com/sun/star/lang/XTypeProvider.hpp>

#include "ftpdirp.hxx"
#include "ftpurl.hxx"

namespace ftp {

    class FTPContentProvider;

    class FTPContentIdentifier
        : public cppu::OWeakObject,
          public com::sun::star::lang::XTypeProvider,
          public com::sun::star::ucb::XContentIdentifier
    {
    public:

        FTPContentIdentifier(const rtl::OUString& ident);

        ~FTPContentIdentifier();

        // XInterface

        virtual com::sun::star::uno::Any SAL_CALL
        queryInterface( const com::sun::star::uno::Type& rType )
            throw( com::sun::star::uno::RuntimeException );

        virtual void SAL_CALL acquire( void ) throw();

        virtual void SAL_CALL release( void ) throw();

        // XTypeProvider

        virtual
        com::sun::star::uno::Sequence<com::sun::star::uno::Type> SAL_CALL
        getTypes(
        )
            throw(
                com::sun::star::uno::RuntimeException
            );

        virtual com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
        getImplementationId(
        )
            throw(
                com::sun::star::uno::RuntimeException
            );

        // XContentIdentifier

        virtual ::rtl::OUString SAL_CALL
        getContentIdentifier(
        )
            throw (
                com::sun::star::uno::RuntimeException
            );

        virtual ::rtl::OUString SAL_CALL
        getContentProviderScheme(
        )
            throw (
                ::com::sun::star::uno::RuntimeException
            );

    private:

        rtl::OUString m_ident;
    };

}

#endif
<|endoftext|>


<commit_before>#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS // to use freopen
#endif

#include <iostream>
#include <thread>
#include <cryptopp/integer.h>
#include <boost/filesystem.hpp>

#ifndef _WIN32
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#endif

#include "Log.h"
#include "base64.h"
#include "Transports.h"
#include "NTCPSession.h"
#include "RouterInfo.h"
#include "RouterContext.h"
#include "Tunnel.h"
#include "NetDb.h"
#include "HTTPServer.h"
#include "util.h"

// Global
int running = 1;

#ifndef _WIN32
void handle_signal(int sig)
{
  switch (sig)
  {
    case SIGHUP:
      if (i2p::util::config::GetArg("daemon", 0) == 1)
      {
        static bool first=true;
        if (first)
        {
          first=false;
          return;
        }
      }
      LogPrint("Reloading config.");
      i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
    break;
    case SIGABRT:
    case SIGTERM:
    case SIGINT:
      running = 0; // Exit loop
    break;
  }
}
#endif

int main( int argc, char* argv[] )
{
  i2p::util::config::OptionParser(argc,argv);
#ifdef _WIN32
  setlocale(LC_CTYPE, "");
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
  setlocale(LC_ALL, "Russian");
#endif

  LogPrint("\n\n\n\ni2pd starting\n");
  LogPrint("data directory: ", i2p::util::filesystem::GetDataDir().string());
  i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);

#ifndef _WIN32
  if (i2p::util::config::GetArg("-daemon", 0) == 1)
  {
    pid_t pid;
    pid = fork();
    if (pid > 0)
    {
      g_Log.Stop();
      return 0;
    }
    if (pid < 0)
    {
      return -1;
    }

    umask(0);
    int sid = setsid();
    if (sid < 0)
    {
      LogPrint("Error, could not create process group.");
      return -1;
    }
    chdir(i2p::util::filesystem::GetDataDir().string().c_str());
  }

  // Pidfile
  std::string pidfile = i2p::util::filesystem::GetDataDir().string();
  pidfile.append("/i2pd.pid");
  int pidFilehandle = open(pidfile.c_str(), O_RDWR|O_CREAT, 0600);
  if (pidFilehandle == -1 )
  {
    LogPrint("Error, could not create pid file (", pidfile, ")\nIs an instance already running?");
    return -1;
  }
  if (lockf(pidFilehandle,F_TLOCK,0) == -1)
  {
    LogPrint("Error, could not lock pid file (", pidfile, ")\nIs an instance already running?");
    return -1;
  }
  char pid[10];
  sprintf(pid,"%d\n",getpid());
  write(pidFilehandle, pid, strlen(pid));

  // Signal handler
  struct sigaction sa;
  sa.sa_handler = handle_signal;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = SA_RESTART;
  sigaction(SIGHUP,&sa,0);
  sigaction(SIGABRT,&sa,0);
  sigaction(SIGTERM,&sa,0);
  sigaction(SIGINT,&sa,0);
#endif

  if (i2p::util::config::GetArg("-log", 0) == 1)
  {
    std::string logfile = i2p::util::filesystem::GetDataDir().string();
#ifndef _WIN32
    logfile.append("/debug.log");
#else
    logfile.append("\\debug.log");
#endif
    LogPrint("Logging to file enabled.");
    freopen(logfile.c_str(),"a",stdout);
  }

  //TODO: This is an ugly workaround. fix it.
  //TODO: Autodetect public IP.
  i2p::context.OverrideNTCPAddress(i2p::util::config::GetCharArg("-host", "127.0.0.1"),
      i2p::util::config::GetArg("-port", 17070));

  i2p::util::HTTPServer httpServer (i2p::util::config::GetArg("-httpport", 7070));

  httpServer.Start ();
  i2p::data::netdb.Start ();
  i2p::transports.Start ();
  i2p::tunnel::tunnels.Start ();

  while (running)
  {
    //TODO Meeh: Find something better to do here.
    std::this_thread::sleep_for (std::chrono::seconds(1));
  }
  LogPrint("Shutdown started.");

  i2p::tunnel::tunnels.Stop ();
  i2p::transports.Stop ();
  i2p::data::netdb.Stop ();
  httpServer.Stop ();

  if (i2p::util::config::GetArg("-log", 0) == 1)
  {
    fclose (stdout);
  }
#ifndef _WIN32
  close(pidFilehandle);
  unlink(pidfile.c_str());
#endif
  return 0;
}
<commit_msg>defining vars should cost less than function calls<commit_after>#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS // to use freopen
#endif

#include <iostream>
#include <thread>
#include <cryptopp/integer.h>
#include <boost/filesystem.hpp>

#ifndef _WIN32
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#endif

#include "Log.h"
#include "base64.h"
#include "Transports.h"
#include "NTCPSession.h"
#include "RouterInfo.h"
#include "RouterContext.h"
#include "Tunnel.h"
#include "NetDb.h"
#include "HTTPServer.h"
#include "util.h"

// Global
int running = 1;
int isDaemon;

#ifndef _WIN32
void handle_signal(int sig)
{
  switch (sig)
  {
    case SIGHUP:
      if (i2p::util::config::GetArg("daemon", 0) == 1)
      {
        static bool first=true;
        if (first)
        {
          first=false;
          return;
        }
      }
      LogPrint("Reloading config.");
      i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
    break;
    case SIGABRT:
    case SIGTERM:
    case SIGINT:
      running = 0; // Exit loop
    break;
  }
}
#endif

int main( int argc, char* argv[] )
{
  i2p::util::config::OptionParser(argc,argv);
  isDaemon = i2p::util::config::GetArg("-daemon", 0);
#ifdef _WIN32
  setlocale(LC_CTYPE, "");
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
  setlocale(LC_ALL, "Russian");
#endif

  LogPrint("\n\n\n\ni2pd starting\n");
  LogPrint("data directory: ", i2p::util::filesystem::GetDataDir().string());
  i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);

  int isLogging = i2p::util::config::GetArg("-log", 0);
  if (isLogging == 1)
  {
    std::string logfile = i2p::util::filesystem::GetDataDir().string();
#ifndef _WIN32
    logfile.append("/debug.log");
#else
    logfile.append("\\debug.log");
#endif
    freopen(logfile.c_str(),"a",stdout);
    LogPrint("Logging to file enabled.");
  }

#ifndef _WIN32
  if (isDaemon == 1)
  {
    pid_t pid;
    pid = fork();
    if (pid > 0)
    {
      g_Log.Stop();
      return 0;
    }
    if (pid < 0)
    {
      return -1;
    }

    umask(0);
    int sid = setsid();
    if (sid < 0)
    {
      LogPrint("Error, could not create process group.");
      return -1;
    }
    chdir(i2p::util::filesystem::GetDataDir().string().c_str());
  }

  // Pidfile
  std::string pidfile = i2p::util::filesystem::GetDataDir().string();
  pidfile.append("/i2pd.pid");
  int pidFilehandle = open(pidfile.c_str(), O_RDWR|O_CREAT, 0600);
  if (pidFilehandle == -1 )
  {
    LogPrint("Error, could not create pid file (", pidfile, ")\nIs an instance already running?");
    return -1;
  }
  if (lockf(pidFilehandle,F_TLOCK,0) == -1)
  {
    LogPrint("Error, could not lock pid file (", pidfile, ")\nIs an instance already running?");
    return -1;
  }
  char pid[10];
  sprintf(pid,"%d\n",getpid());
  write(pidFilehandle, pid, strlen(pid));

  // Signal handler
  struct sigaction sa;
  sa.sa_handler = handle_signal;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = SA_RESTART;
  sigaction(SIGHUP,&sa,0);
  sigaction(SIGABRT,&sa,0);
  sigaction(SIGTERM,&sa,0);
  sigaction(SIGINT,&sa,0);
#endif

  //TODO: This is an ugly workaround. fix it.
  //TODO: Autodetect public IP.
  i2p::context.OverrideNTCPAddress(i2p::util::config::GetCharArg("-host", "127.0.0.1"),
      i2p::util::config::GetArg("-port", 17070));

  i2p::util::HTTPServer httpServer (i2p::util::config::GetArg("-httpport", 7070));

  httpServer.Start ();
  i2p::data::netdb.Start ();
  i2p::transports.Start ();
  i2p::tunnel::tunnels.Start ();

  while (running)
  {
    //TODO Meeh: Find something better to do here.
    std::this_thread::sleep_for (std::chrono::seconds(1));
  }
  LogPrint("Shutdown started.");

  i2p::tunnel::tunnels.Stop ();
  i2p::transports.Stop ();
  i2p::data::netdb.Stop ();
  httpServer.Stop ();

  if (isLogging == 1)
  {
    fclose (stdout);
  }
#ifndef _WIN32
  close(pidFilehandle);
  unlink(pidfile.c_str());
#endif
  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007 Tommi Maekitalo
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <cxxtools/propertiesparser.h>
#include <cxxtools/utf8codec.h>
#include <iostream>
#include <sstream>
#include <cctype>

namespace cxxtools
{
  namespace
  {
    std::string mkErrorMessage(const std::string& msg, unsigned lineNo)
    {
      std::ostringstream s;
      s << "parsing properties failed in line " << lineNo << ": " << msg;
      return s.str();
    }
  }

  PropertiesParserError::PropertiesParserError(const std::string& msg, unsigned lineNo)
    : SerializationError(mkErrorMessage(msg, lineNo))
  { }

  void PropertiesParser::parse(std::istream& in, TextCodec<Char, char>* codec)
  {
    TextIStream ts(in, codec ? codec : new Utf8Codec());
    parse(ts);
  }

  void PropertiesParser::parse(std::basic_istream<Char>& in)
  {
    Char ch;
    while (in.get(ch) && !advance(ch))
      ;
    end();
  }

  bool PropertiesParser::advance(Char ch)
  {
    bool ret = false;

    if (ch == '\n')
      ++_lineNo;

    switch (_state)
    {
      case state_0:
        if (ch == '#' || ch == '!')
          _state = state_comment;
        else if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
          ;
        else if (ch == '\\')
        {
          _key.clear();
          _keypart.clear();
          _state = state_key_esc;
        }
        else
        {
          _key = ch;
          _keypart = ch;
          _state = state_key;
        }
        break;

      case state_key:
        if (ch == '.')
        {
          _event.onKeyPart(_keypart);
          _keypart.clear();
          _key += ch;
        }
        else if (ch == '\r' || ch == '\n')
        {
          ret = _event.onKeyPart(_keypart)
             || _event.onKey(_key)
             || _event.onValue(String());
          _keypart.clear();
          _key.clear();
        }
        else if (std::isspace(ch.value()))
        {
          ret = _event.onKeyPart(_keypart)
             || _event.onKey(_key);
          _state = state_key_sp;
        }
        else if (ch == '=' || ch == ':')
        {
          ret = _event.onKeyPart(_keypart)
             || _event.onKey(_key);
          _state = state_value0;
        }
        else if (ch == '\\')
        {
          _state = state_key_esc;
        }
        else
        {
          _keypart += ch;
          _key += ch;
        }
        break;

      case state_key_esc:
        if (ch == 'u')
        {
          _unicode = 0;
          _unicodeCount = 0;
          _state = state_key_unicode;
        }
        else if (ch == 'n')
        {
          _keypart += '\n';
          _key += '\n';
          _state = state_key;
        }
        else if (ch == 'r')
        {
          _keypart += '\r';
          _key += '\r';
          _state = state_key;
        }
        else if (ch == 't')
        {
          _keypart += '\t';
          _key += '\t';
          _state = state_key;
        }
        else
        {
          _keypart += ch;
          _key += ch;
          _state = state_key;
        }
        break;

      case state_key_sp:
        if (ch == '=' || ch == ':')
        {
          _state = state_value0;
        }
        else if (ch == '\r' || ch == '\n')
        {
          ret = _event.onValue(String());
          _keypart.clear();
          _key.clear();
          _state = state_key;
        }
        else if (ch == '\\')
        {
          _value.clear();
          _state = state_value_esc;
        }
        else if (!std::isspace(ch.value()))
        {
          _value = ch;
          _state = state_value;
        }
        break;

      case state_value0:
        if (ch == '\n')
        {
          ret = _event.onValue(_value);
          _value.clear();
          _state = state_0;
        }
        else if (ch == '\\')
          _state = state_value_esc;
        else if (!std::isspace(ch.value()))
        {
          _value = ch;
          _state = state_value;
        }
        break;

      case state_value:
        if (ch == '\n')
        {
          ret = _event.onValue(_value);
          _value.clear();
          _state = state_0;
        }
        else if (ch == '\\')
          _state = state_value_esc;
        else if (_trim && std::isspace(ch.value()))
        {
          _space = ch;
          _state = state_value_space;
        }
        else
          _value += ch;
        break;

      case state_value_esc:
        if (ch == 'u')
        {
          _unicode = 0;
          _unicodeCount = 0;
          _state = state_unicode;
        }
        else if (ch == 'n')
        {
          _value += '\n';
          _state = state_value;
        }
        else if (ch == 'r')
        {
          _value += '\r';
          _state = state_value;
        }
        else if (ch == 't')
        {
          _value += '\t';
          _state = state_value;
        }
        else if (ch == '\r' || ch == '\n')
        {
          _state = state_value_cont;
        }
        else
        {
          _value += ch;
          _state = state_value;
        }
        break;

      case state_value_cont:
        if (ch == '\n')
        {
          ret = _event.onValue(_value);
          _value.clear();
          _state = state_0;
        }
        else if (ch == '\\')
          _state = state_value_esc;
        else if (!std::isspace(ch.value()))
        {
          _value += ch;
          _state = state_value;
        }
        break;

      case state_value_space:
        if (ch == '\n')
        {
          ret = _event.onValue(_value);
          _value.clear();
          _state = state_0;
        }
        else if (ch == '\\')
        {
          _value += _space;
          _state = state_value_esc;
        }
        else if (std::isspace(ch.value()))
        {
          _space += ch;
        }
        else
        {
          _value += _space;
          _value += ch;
          _state = state_value;
        }
        break;

      case state_unicode:
      case state_key_unicode:
        if (ch >= '0' && ch <= '9')
        {
          _unicode = (_unicode << 4) | (ch - '0');
          ++_unicodeCount;
        }
        else if (ch >= 'a' && ch <= 'f')
        {
          _unicode = (_unicode << 4) | (ch - 'a' + 10);
          ++_unicodeCount;
        }
        else if (ch >= 'A' && ch <= 'F')
        {
          _unicode = (_unicode << 4) | (ch - 'A' + 10);
          ++_unicodeCount;
        }
        else if (_unicodeCount == 0)
          throw PropertiesParserError(std::string("invalid unicode sequence \\u") + ch.narrow() + " in properties", _lineNo);
        else
        {
          if (_state == state_unicode)
          {
            _state = state_value;
            _value += Char(_unicode);
          }
          else
          {
            _state = state_key;
            _key += Char(_unicode);
            _keypart += Char(_unicode);
          }

          return advance(ch);
        }

        if (_unicodeCount >= 8)
        {
          if (_state == state_unicode)
          {
            _state = state_value;
            _value += Char(_unicode);
          }
          else
          {
            _state = state_key;
            _key += Char(_unicode);
          }

          return false;
        }

        break;

      case state_comment:
        if (ch == '\n')
          _state = state_0;
        break;
    }

    return ret;
  }

  void PropertiesParser::end()
  {
    switch (_state)
    {
      case state_value0:
      case state_value:
      case state_value_cont:
      case state_value_esc:
      case state_key_sp:
        _event.onValue(_value);
        _value.clear();
        break;

      case state_value_space:
        _event.onValue(_value + _space);
        _value.clear();
        break;

      case state_key:
          _event.onKeyPart(_keypart)
             || _event.onKey(_key)
             || _event.onValue(String());
          break;

      case state_unicode:
        if (_unicodeCount == 0)
          throw PropertiesParserError("invalid unicode sequence at end of json", _lineNo);

        _value += Char(_unicode);
        _event.onValue(_value);
        _value.clear();
        break;

      case state_0:
      case state_comment:
        break;

      case state_key_esc:
      case state_key_unicode:
        throw PropertiesParserError("parse error while reading key " + Utf8Codec::encode(_key) + " in properties", _lineNo);
    }
  }

}
<commit_msg>fix text of error message in propertiesparser<commit_after>/*
 * Copyright (C) 2007 Tommi Maekitalo
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <cxxtools/propertiesparser.h>
#include <cxxtools/utf8codec.h>
#include <iostream>
#include <sstream>
#include <cctype>

namespace cxxtools
{
  namespace
  {
    std::string mkErrorMessage(const std::string& msg, unsigned lineNo)
    {
      std::ostringstream s;
      s << "parsing properties failed in line " << lineNo << ": " << msg;
      return s.str();
    }
  }

  PropertiesParserError::PropertiesParserError(const std::string& msg, unsigned lineNo)
    : SerializationError(mkErrorMessage(msg, lineNo))
  { }

  void PropertiesParser::parse(std::istream& in, TextCodec<Char, char>* codec)
  {
    TextIStream ts(in, codec ? codec : new Utf8Codec());
    parse(ts);
  }

  void PropertiesParser::parse(std::basic_istream<Char>& in)
  {
    Char ch;
    while (in.get(ch) && !advance(ch))
      ;
    end();
  }

  bool PropertiesParser::advance(Char ch)
  {
    bool ret = false;

    if (ch == '\n')
      ++_lineNo;

    switch (_state)
    {
      case state_0:
        if (ch == '#' || ch == '!')
          _state = state_comment;
        else if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
          ;
        else if (ch == '\\')
        {
          _key.clear();
          _keypart.clear();
          _state = state_key_esc;
        }
        else
        {
          _key = ch;
          _keypart = ch;
          _state = state_key;
        }
        break;

      case state_key:
        if (ch == '.')
        {
          _event.onKeyPart(_keypart);
          _keypart.clear();
          _key += ch;
        }
        else if (ch == '\r' || ch == '\n')
        {
          ret = _event.onKeyPart(_keypart)
             || _event.onKey(_key)
             || _event.onValue(String());
          _keypart.clear();
          _key.clear();
        }
        else if (std::isspace(ch.value()))
        {
          ret = _event.onKeyPart(_keypart)
             || _event.onKey(_key);
          _state = state_key_sp;
        }
        else if (ch == '=' || ch == ':')
        {
          ret = _event.onKeyPart(_keypart)
             || _event.onKey(_key);
          _state = state_value0;
        }
        else if (ch == '\\')
        {
          _state = state_key_esc;
        }
        else
        {
          _keypart += ch;
          _key += ch;
        }
        break;

      case state_key_esc:
        if (ch == 'u')
        {
          _unicode = 0;
          _unicodeCount = 0;
          _state = state_key_unicode;
        }
        else if (ch == 'n')
        {
          _keypart += '\n';
          _key += '\n';
          _state = state_key;
        }
        else if (ch == 'r')
        {
          _keypart += '\r';
          _key += '\r';
          _state = state_key;
        }
        else if (ch == 't')
        {
          _keypart += '\t';
          _key += '\t';
          _state = state_key;
        }
        else
        {
          _keypart += ch;
          _key += ch;
          _state = state_key;
        }
        break;

      case state_key_sp:
        if (ch == '=' || ch == ':')
        {
          _state = state_value0;
        }
        else if (ch == '\r' || ch == '\n')
        {
          ret = _event.onValue(String());
          _keypart.clear();
          _key.clear();
          _state = state_key;
        }
        else if (ch == '\\')
        {
          _value.clear();
          _state = state_value_esc;
        }
        else if (!std::isspace(ch.value()))
        {
          _value = ch;
          _state = state_value;
        }
        break;

      case state_value0:
        if (ch == '\n')
        {
          ret = _event.onValue(_value);
          _value.clear();
          _state = state_0;
        }
        else if (ch == '\\')
          _state = state_value_esc;
        else if (!std::isspace(ch.value()))
        {
          _value = ch;
          _state = state_value;
        }
        break;

      case state_value:
        if (ch == '\n')
        {
          ret = _event.onValue(_value);
          _value.clear();
          _state = state_0;
        }
        else if (ch == '\\')
          _state = state_value_esc;
        else if (_trim && std::isspace(ch.value()))
        {
          _space = ch;
          _state = state_value_space;
        }
        else
          _value += ch;
        break;

      case state_value_esc:
        if (ch == 'u')
        {
          _unicode = 0;
          _unicodeCount = 0;
          _state = state_unicode;
        }
        else if (ch == 'n')
        {
          _value += '\n';
          _state = state_value;
        }
        else if (ch == 'r')
        {
          _value += '\r';
          _state = state_value;
        }
        else if (ch == 't')
        {
          _value += '\t';
          _state = state_value;
        }
        else if (ch == '\r' || ch == '\n')
        {
          _state = state_value_cont;
        }
        else
        {
          _value += ch;
          _state = state_value;
        }
        break;

      case state_value_cont:
        if (ch == '\n')
        {
          ret = _event.onValue(_value);
          _value.clear();
          _state = state_0;
        }
        else if (ch == '\\')
          _state = state_value_esc;
        else if (!std::isspace(ch.value()))
        {
          _value += ch;
          _state = state_value;
        }
        break;

      case state_value_space:
        if (ch == '\n')
        {
          ret = _event.onValue(_value);
          _value.clear();
          _state = state_0;
        }
        else if (ch == '\\')
        {
          _value += _space;
          _state = state_value_esc;
        }
        else if (std::isspace(ch.value()))
        {
          _space += ch;
        }
        else
        {
          _value += _space;
          _value += ch;
          _state = state_value;
        }
        break;

      case state_unicode:
      case state_key_unicode:
        if (ch >= '0' && ch <= '9')
        {
          _unicode = (_unicode << 4) | (ch - '0');
          ++_unicodeCount;
        }
        else if (ch >= 'a' && ch <= 'f')
        {
          _unicode = (_unicode << 4) | (ch - 'a' + 10);
          ++_unicodeCount;
        }
        else if (ch >= 'A' && ch <= 'F')
        {
          _unicode = (_unicode << 4) | (ch - 'A' + 10);
          ++_unicodeCount;
        }
        else if (_unicodeCount == 0)
          throw PropertiesParserError(std::string("invalid unicode sequence \\u") + ch.narrow() + " in properties", _lineNo);
        else
        {
          if (_state == state_unicode)
          {
            _state = state_value;
            _value += Char(_unicode);
          }
          else
          {
            _state = state_key;
            _key += Char(_unicode);
            _keypart += Char(_unicode);
          }

          return advance(ch);
        }

        if (_unicodeCount >= 8)
        {
          if (_state == state_unicode)
          {
            _state = state_value;
            _value += Char(_unicode);
          }
          else
          {
            _state = state_key;
            _key += Char(_unicode);
          }

          return false;
        }

        break;

      case state_comment:
        if (ch == '\n')
          _state = state_0;
        break;
    }

    return ret;
  }

  void PropertiesParser::end()
  {
    switch (_state)
    {
      case state_value0:
      case state_value:
      case state_value_cont:
      case state_value_esc:
      case state_key_sp:
        _event.onValue(_value);
        _value.clear();
        break;

      case state_value_space:
        _event.onValue(_value + _space);
        _value.clear();
        break;

      case state_key:
          _event.onKeyPart(_keypart)
             || _event.onKey(_key)
             || _event.onValue(String());
          break;

      case state_unicode:
        if (_unicodeCount == 0)
          throw PropertiesParserError("invalid unicode sequence at end of properties", _lineNo);

        _value += Char(_unicode);
        _event.onValue(_value);
        _value.clear();
        break;

      case state_0:
      case state_comment:
        break;

      case state_key_esc:
      case state_key_unicode:
        throw PropertiesParserError("parse error while reading key " + Utf8Codec::encode(_key) + " in properties", _lineNo);
    }
  }

}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "uritests.h"

#include "guiutil.h"
#include "walletmodel.h"

#include <QUrl>

void URITests::uriTests()
{
    SendCoinsRecipient rv;
    QUrl uri;
    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-dontexist="));
    QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv));

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?dontexist="));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString());
    QVERIFY(rv.amount == 0);

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?label=Wikipedia Example Address"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString("Wikipedia Example Address"));
    QVERIFY(rv.amount == 0);

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=0.001"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString());
    QVERIFY(rv.amount == 100000);

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1.001"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString());
    QVERIFY(rv.amount == 100100000);

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=100&label=Wikipedia Example"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.amount == 10000000000LL);
    QVERIFY(rv.label == QString("Wikipedia Example"));

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString());

    QVERIFY(GUIUtil::parseBitcoinURI("bitcoincash://175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address", &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString());

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-message=Wikipedia Example Address"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000&label=Wikipedia Example"));
    QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv));

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000.0&label=Wikipedia Example"));
    QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv));
}
<commit_msg>[qt] initialize chainparams in uri test<commit_after>// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "uritests.h"

#include "guiutil.h"
#include "walletmodel.h"
#include "chainparams.h"

#include <QUrl>

void URITests::uriTests()
{
    // UAHF status is checked to determine if
    // prefix is bitcoin: or bitcoincash:
    // This requires chainparams to be initialized.
    SelectParams(CBaseChainParams::MAIN);

    SendCoinsRecipient rv;
    QUrl uri;
    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-dontexist="));
    QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv));

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?dontexist="));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString());
    QVERIFY(rv.amount == 0);

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?label=Wikipedia Example Address"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString("Wikipedia Example Address"));
    QVERIFY(rv.amount == 0);

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=0.001"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString());
    QVERIFY(rv.amount == 100000);

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1.001"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString());
    QVERIFY(rv.amount == 100100000);

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=100&label=Wikipedia Example"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.amount == 10000000000LL);
    QVERIFY(rv.label == QString("Wikipedia Example"));

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString());

    QVERIFY(GUIUtil::parseBitcoinURI("bitcoincash://175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address", &rv));
    QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
    QVERIFY(rv.label == QString());

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-message=Wikipedia Example Address"));
    QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv));

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000&label=Wikipedia Example"));
    QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv));

    uri.setUrl(QString("bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000.0&label=Wikipedia Example"));
    QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv));
}
<|endoftext|>