<commit_before>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:

#include "file_description.h"
#include "real_syscalls.h"
#include "backup_debug.h"

#include "assert.h"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

///////////////////////////////////////////////////////////////////////////////
//
// file_description() -
//
// Description:
//
//     ...
//
file_description::file_description()
: m_refcount(1), m_offset(0), m_fd_in_dest_space(-1), m_name(NULL)
{}

///////////////////////////////////////////////////////////////////////////////
//
// print() -
//
// Description:
//
//     Usefull print out of file description state.
//
void file_description::print() {
    printf("======================\n");
    printf("file_description: %s, @%p\n", m_name, this);
    printf("refcount:%d, offset:%ld, fd_in_dest_space:%d\n",
            this->m_refcount, this->m_offset, this->m_fd_in_dest_space);
    printf("======================\n");
}

///////////////////////////////////////////////////////////////////////////////
//
void file_description::set_name(char *name)
{
    m_name = name;
}

///////////////////////////////////////////////////////////////////////////////
//
// open() -
//
// Description:
//
//     Calls the operating system's open() syscall for the current
// file description.  This also sets the file descriptor in the
// destination/backup space for the backup copy of the original file.
//
// Notes:
//
//     Open assumes that the backup file exists.  Create assumes the
// backup file does NOT exist.
//
void file_description::open()
{
    int fd = 0;
    fd = call_real_open(m_name, O_WRONLY, 0777);
    if (fd < 0) {
        int error = errno;
        assert(error == ENOENT);
        this->create();
    } else {
        this->m_fd_in_dest_space = fd;
    }
}

///////////////////////////////////////////////////////////////////////////////
//
// create() -
//
// Description:
//
//     Calls the operating system's open() syscall with the create
// flag for the current file description.  This also sets the file
// descriptor in the destination/backup space for the backup
// copy of the original file.
//
// Notes:
//
//     Open assumes that the backup file exists.  Create assumes the
// backup file does NOT exist.
//
void file_description::create()
{
    // Create file that was just opened, this assumes the parent directories
    // exist.
    int fd = 0;
    fd = call_real_open(m_name, O_CREAT | O_WRONLY, 0777);
    if (fd < 0) {
        int error = errno;
        perror("[UhOh]: <CAPTURE> ");
        assert(error == EEXIST);
        fd = call_real_open(m_name, O_WRONLY, 0777);
        if (fd < 0) {
            perror("BACKUP: Couldn't open backup copy of recently opened file.");
            abort();
        }
    }

    this->m_fd_in_dest_space = fd;
}

///////////////////////////////////////////////////////////////////////////////
//
// close() -
//
// Description:
//
//     ...
//
void file_description::close()
{
    // TODO: Check refcount, if it's zero we REALLY have to close
    // the file.  Otherwise, if there are any references left,
    // we can only decrement the refcount; other file descriptors
    // are still open in the main application.

    int r = 0;
    r = call_real_close(this->m_fd_in_dest_space);
    if (r != 0) {
        perror("BACKUP: close() of backup file failed.");
        abort();
    }
}

///////////////////////////////////////////////////////////////////////////////
//
// write() -
//
// Description:
//
//     ...
//
void file_description::write(const void *buf, size_t nbyte)
{
    ssize_t r = 0;
    r = call_real_write(this->m_fd_in_dest_space, buf, nbyte);
    if (r < 0) {
        perror("BACKUP: write() to backup file failed.");
        abort();
    }

    this->m_offset = r;
}

///////////////////////////////////////////////////////////////////////////////
//
// seek() -
//
// Description:
//
//     ...
//
void file_description::seek(size_t nbyte)
{
    // Do we need to seek nbytes past the current position?
    // Past an absolute position?
    // <CER> this depends on the caller...
    int whence = SEEK_SET;
    off_t offset = 0;
    offset = lseek(this->m_fd_in_dest_space, nbyte, whence);
    if (offset < 0) {
        perror("BACKUP: lseek() failed.");
        abort();
    }
    this->m_offset = offset;
}

///////////////////////////////////////////////////////////////////////////////
//
// pwrite() -
//
// Description:
//
//     ...
//
void file_description::pwrite(const void *buf, size_t nbyte, off_t offset)
{
    ssize_t r = 0;
    r = call_real_pwrite(this->m_fd_in_dest_space, buf, nbyte, offset);
    if (r < 0) {
        perror("BACKUP: pwrite() to backup file failed.");
        abort();
    }
}
<commit_msg>refs #5599 Modifying traces for bug.<commit_after>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:

#include "file_description.h"
#include "real_syscalls.h"
#include "backup_debug.h"

#include "assert.h"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

///////////////////////////////////////////////////////////////////////////////
//
// file_description() -
//
// Description:
//
//     ...
//
file_description::file_description()
: m_refcount(1), m_offset(0), m_fd_in_dest_space(-1), m_name(NULL)
{}

///////////////////////////////////////////////////////////////////////////////
//
// print() -
//
// Description:
//
//     Usefull print out of file description state.
//
void file_description::print() {
    printf("======================\n");
    printf("file_description: %s, @%p\n", m_name, this);
    printf("refcount:%d, offset:%ld, fd_in_dest_space:%d\n",
            this->m_refcount, this->m_offset, this->m_fd_in_dest_space);
    printf("======================\n");
}

///////////////////////////////////////////////////////////////////////////////
//
void file_description::set_name(char *name)
{
    m_name = name;
}

///////////////////////////////////////////////////////////////////////////////
//
// open() -
//
// Description:
//
//     Calls the operating system's open() syscall for the current
// file description.  This also sets the file descriptor in the
// destination/backup space for the backup copy of the original file.
//
// Notes:
//
//     Open assumes that the backup file exists.  Create assumes the
// backup file does NOT exist.
//
void file_description::open()
{
    int fd = 0;
    fd = call_real_open(m_name, O_WRONLY, 0777);
    if (fd < 0) {
        int error = errno;
        if(error != ENOENT) {
            perror("ERROR: <CAPTURE> ");
            this->print();
        }

        assert(error == ENOENT);
        this->create();
    } else {
        this->m_fd_in_dest_space = fd;
    }
}

///////////////////////////////////////////////////////////////////////////////
//
// create() -
//
// Description:
//
//     Calls the operating system's open() syscall with the create
// flag for the current file description.  This also sets the file
// descriptor in the destination/backup space for the backup
// copy of the original file.
//
// Notes:
//
//     Open assumes that the backup file exists.  Create assumes the
// backup file does NOT exist.
//
void file_description::create()
{
    // Create file that was just opened, this assumes the parent directories
    // exist.
    int fd = 0;
    fd = call_real_open(m_name, O_CREAT | O_WRONLY, 0777);
    if (fd < 0) {
        int error = errno;
        if (error != EEXIST) {
            perror("ERROR: <CAPTURE> ");
            this->print();
        }

        assert(error == EEXIST);
        fd = call_real_open(m_name, O_WRONLY, 0777);
        if (fd < 0) {
            perror("BACKUP: Couldn't open backup copy of recently opened file.");
            abort();
        }
    }

    this->m_fd_in_dest_space = fd;
}

///////////////////////////////////////////////////////////////////////////////
//
// close() -
//
// Description:
//
//     ...
//
void file_description::close()
{
    // TODO: Check refcount, if it's zero we REALLY have to close
    // the file.  Otherwise, if there are any references left,
    // we can only decrement the refcount; other file descriptors
    // are still open in the main application.

    int r = 0;
    r = call_real_close(this->m_fd_in_dest_space);
    if (r != 0) {
        perror("BACKUP: close() of backup file failed.");
        abort();
    }
}

///////////////////////////////////////////////////////////////////////////////
//
// write() -
//
// Description:
//
//     ...
//
void file_description::write(const void *buf, size_t nbyte)
{
    ssize_t r = 0;
    r = call_real_write(this->m_fd_in_dest_space, buf, nbyte);
    if (r < 0) {
        perror("BACKUP: write() to backup file failed.");
        abort();
    }

    this->m_offset = r;
}

///////////////////////////////////////////////////////////////////////////////
//
// seek() -
//
// Description:
//
//     ...
//
void file_description::seek(size_t nbyte)
{
    // Do we need to seek nbytes past the current position?
    // Past an absolute position?
    // <CER> this depends on the caller...
    int whence = SEEK_SET;
    off_t offset = 0;
    offset = lseek(this->m_fd_in_dest_space, nbyte, whence);
    if (offset < 0) {
        perror("BACKUP: lseek() failed.");
        abort();
    }
    this->m_offset = offset;
}

///////////////////////////////////////////////////////////////////////////////
//
// pwrite() -
//
// Description:
//
//     ...
//
void file_description::pwrite(const void *buf, size_t nbyte, off_t offset)
{
    ssize_t r = 0;
    r = call_real_pwrite(this->m_fd_in_dest_space, buf, nbyte, offset);
    if (r < 0) {
        perror("BACKUP: pwrite() to backup file failed.");
        abort();
    }
}
<|endoftext|>


<commit_before>/***************************************************************************
*   Copyright (C) 2003 by                                                 *
*   Cyril Bosselut (bosselut@b1project.com)                               *
*                                                                         *
*   Copyright (C) 2003-2005 by                                            *
*   Jason Kivlighn (mizunoami44@users.sourceforge.net)                    *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
***************************************************************************/

#include "kreexport.h"

#include <qfile.h>
#include <qstylesheet.h>
#include <qbuffer.h>
#include <qimage.h>

#include <kdebug.h>
#include <klocale.h>
#include <kmdcodec.h>
#include <kglobal.h>
#include <kstandarddirs.h>

#include "backends/recipedb.h"

KreExporter::KreExporter( CategoryTree *_categories, const QString& filename, const QString &format ) :
		BaseExporter( filename, format ), categories( _categories )
{
	if ( format == "*.kre" ) {
		setCompressed(true);
	}
}

KreExporter::~KreExporter()
{
	delete categories;
}

int KreExporter::headerFlags() const
{
	return RecipeDB::Categories;
}

QString KreExporter::createHeader( const RecipeList& recipes )
{
	QString xml;

	xml += "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
	xml += "<krecipes version=\"" + krecipes_version() + "\" lang=\"" + ( KGlobal::locale() )->language() + "\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"krecipes.xsd\">\n";

	createCategoryStructure( xml, recipes );

	return xml;
}

QString KreExporter::createFooter()
{
	return "</krecipes>\n";
}

//TODO: use QDOM (see recipemlexporter.cpp)?
QString KreExporter::createContent( const RecipeList& recipes )
{
	QString xml;

	RecipeList::const_iterator recipe_it;
	for ( recipe_it = recipes.begin(); recipe_it != recipes.end(); ++recipe_it ) {

		xml += "<krecipes-recipe>\n";
		xml += "<krecipes-description>\n";
		xml += "<title>" + QStyleSheet::escape( ( *recipe_it ).title.utf8() ) + "</title>\n";

		for ( ElementList::const_iterator author_it = ( *recipe_it ).authorList.begin(); author_it != ( *recipe_it ).authorList.end(); ++author_it )
			xml += "<author>" + QStyleSheet::escape( ( *author_it ).name.utf8() ) + "</author>\n";

		xml += "<pictures>\n";
		if ( !( *recipe_it ).photo.isNull() ) {
			xml += "<pic format=\"JPEG\" id=\"1\"><![CDATA["; //fixed id until we implement multiple photos ability
			QByteArray data;
			QBuffer buffer( data );
			buffer.open( IO_WriteOnly );
			QImageIO iio( &buffer, "JPEG" );
			iio.setImage( ( *recipe_it ).photo.convertToImage() );
			iio.write();
			//( *recipe_it ).photo.save( &buffer, "JPEG" ); don't need QImageIO in QT 3.2

			xml += KCodecs::base64Encode( data, true );

			xml += "]]></pic>\n";
		}
		xml += "</pictures>\n";
		xml += "<category>\n";

		for ( ElementList::const_iterator cat_it = ( *recipe_it ).categoryList.begin(); cat_it != ( *recipe_it ).categoryList.end(); ++cat_it )
			xml += "<cat>" + QStyleSheet::escape( ( *cat_it ).name.utf8() ) + "</cat>\n";

		xml += "</category>\n";
		xml += "<yield>";
		xml += "<amount>";
		if ( ( *recipe_it ).yield.amount_offset < 1e-10 ) {
			xml += QString::number( ( *recipe_it ).yield.amount );
		}
		else {
			xml += "<min>"+QString::number( ( *recipe_it ).yield.amount )+"</min>";
			xml += "<max>"+QString::number( ( *recipe_it ).yield.amount + ( *recipe_it ).yield.amount_offset )+"</max>";
		}
		xml += "</amount>";
		xml += "<type>"+( *recipe_it ).yield.type+"</type>";
		xml += "</yield>\n";
		xml += "<preparation-time>";
		xml += ( *recipe_it ).prepTime.toString( "hh:mm" );
		xml += "</preparation-time>\n";
		xml += "</krecipes-description>\n";
		xml += "<krecipes-ingredients>\n";

		IngredientList list_copy = ( *recipe_it ).ingList;
		for ( IngredientList group_list = list_copy.firstGroup(); group_list.count() != 0; group_list = list_copy.nextGroup() ) {
			QString group = group_list[ 0 ].group; //just use the first's name... they're all the same
			if ( !group.isEmpty() )
				xml += "<ingredient-group name=\"" + group + "\">\n";

			for ( IngredientList::const_iterator ing_it = group_list.begin(); ing_it != group_list.end(); ++ing_it ) {
				xml += "<ingredient>\n";
				xml += "<name>" + QStyleSheet::escape( ( *ing_it ).name.utf8() ) + "</name>\n";
				xml += "<amount>";
				if ( ( *ing_it ).amount_offset < 1e-10 ) {
					xml += QString::number( ( *ing_it ).amount );
				}
				else {
					xml += "<min>"+QString::number( ( *ing_it ).amount )+"</min>";
					xml += "<max>"+QString::number( ( *ing_it ).amount + ( *ing_it ).amount_offset )+"</max>";
				}
				xml += "</amount>\n";
				QString unit_str = ( ( *ing_it ).amount+( *ing_it ).amount_offset > 1 ) ? ( *ing_it ).units.plural : ( *ing_it ).units.name;
				xml += "<unit>" + QStyleSheet::escape( unit_str.utf8() ) + "</unit>\n";
				if ( ( *ing_it ).prepMethodList.count() > 0 )
					xml += "<prep>" + QStyleSheet::escape( ( *ing_it ).prepMethodList.join(",").utf8() ) + "</prep>\n";
				xml += "</ingredient>\n";
			}

			if ( !group.isEmpty() )
				xml += "</ingredient-group>\n";
		}

		/// @todo add ingredient properties

		xml += "</krecipes-ingredients>\n";
		xml += "<krecipes-instructions>\n";
		xml += QStyleSheet::escape( ( *recipe_it ).instructions.utf8() );
		xml += "</krecipes-instructions>\n";
		xml += "</krecipes-recipe>\n";
	}

	return xml;
}

void KreExporter::createCategoryStructure( QString &xml, const RecipeList &recipes )
{
	QValueList<int> categoriesUsed;
	for ( RecipeList::const_iterator recipe_it = recipes.begin(); recipe_it != recipes.end(); ++recipe_it ) {
		for ( ElementList::const_iterator cat_it = ( *recipe_it ).categoryList.begin(); cat_it != ( *recipe_it ).categoryList.end(); ++cat_it ) {
			if ( categoriesUsed.find( ( *cat_it ).id ) == categoriesUsed.end() )
				categoriesUsed << ( *cat_it ).id;
		}
	}

	if ( !categoriesUsed.empty() ) {
		//only keep the relevant category structure
		removeIfUnused( categoriesUsed, categories );

		xml += "<krecipes-category-structure>\n";
		writeCategoryStructure( xml, categories );
		xml += "</krecipes-category-structure>\n";
	}
}

bool KreExporter::removeIfUnused( const QValueList<int> &cat_ids, CategoryTree *parent, bool parent_should_show )
{
	for ( CategoryTree * it = parent->firstChild(); it; it = it->nextSibling() ) {
		if ( cat_ids.find( it->category.id ) != cat_ids.end() ) {
			parent_should_show = true;
			removeIfUnused( cat_ids, it, true ); //still recurse, but doesn't affect 'parent'
		}
		else {
			bool result = removeIfUnused( cat_ids, it );
			if ( parent_should_show == false )
				parent_should_show = result;
		}
	}

	if ( !parent_should_show && parent->category.id != -1 ) {
		//FIXME: CategoryTree is broken when deleting items
		//delete parent;

		parent->category.id = -2; //temporary workaround
	}

	return parent_should_show;
}

void KreExporter::writeCategoryStructure( QString &xml, const CategoryTree *categoryTree )
{
	if ( categoryTree->category.id != -2 ) {
		if ( categoryTree->category.id != -1 )
			xml += "<category name=\"" + QStyleSheet::escape( categoryTree->category.name.utf8() ).replace("\"",""") + "\">\n";

		for ( CategoryTree * child_it = categoryTree->firstChild(); child_it; child_it = child_it->nextSibling() ) {
			writeCategoryStructure( xml, child_it );
		}

		if ( categoryTree->category.id != -1 )
			xml += "</category>\n";
	}
}

<commit_msg>Fix exporting KreML for group names with special XML characters (like '&')<commit_after>/***************************************************************************
*   Copyright (C) 2003 by                                                 *
*   Cyril Bosselut (bosselut@b1project.com)                               *
*                                                                         *
*   Copyright (C) 2003-2005 by                                            *
*   Jason Kivlighn (mizunoami44@users.sourceforge.net)                    *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
***************************************************************************/

#include "kreexport.h"

#include <qfile.h>
#include <qstylesheet.h>
#include <qbuffer.h>
#include <qimage.h>

#include <kdebug.h>
#include <klocale.h>
#include <kmdcodec.h>
#include <kglobal.h>
#include <kstandarddirs.h>

#include "backends/recipedb.h"

KreExporter::KreExporter( CategoryTree *_categories, const QString& filename, const QString &format ) :
		BaseExporter( filename, format ), categories( _categories )
{
	if ( format == "*.kre" ) {
		setCompressed(true);
	}
}

KreExporter::~KreExporter()
{
	delete categories;
}

int KreExporter::headerFlags() const
{
	return RecipeDB::Categories;
}

QString KreExporter::createHeader( const RecipeList& recipes )
{
	QString xml;

	xml += "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
	xml += "<krecipes version=\"" + krecipes_version() + "\" lang=\"" + ( KGlobal::locale() )->language() + "\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"krecipes.xsd\">\n";

	createCategoryStructure( xml, recipes );

	return xml;
}

QString KreExporter::createFooter()
{
	return "</krecipes>\n";
}

//TODO: use QDOM (see recipemlexporter.cpp)?
QString KreExporter::createContent( const RecipeList& recipes )
{
	QString xml;

	RecipeList::const_iterator recipe_it;
	for ( recipe_it = recipes.begin(); recipe_it != recipes.end(); ++recipe_it ) {

		xml += "<krecipes-recipe>\n";
		xml += "<krecipes-description>\n";
		xml += "<title>" + QStyleSheet::escape( ( *recipe_it ).title.utf8() ) + "</title>\n";

		for ( ElementList::const_iterator author_it = ( *recipe_it ).authorList.begin(); author_it != ( *recipe_it ).authorList.end(); ++author_it )
			xml += "<author>" + QStyleSheet::escape( ( *author_it ).name.utf8() ) + "</author>\n";

		xml += "<pictures>\n";
		if ( !( *recipe_it ).photo.isNull() ) {
			xml += "<pic format=\"JPEG\" id=\"1\"><![CDATA["; //fixed id until we implement multiple photos ability
			QByteArray data;
			QBuffer buffer( data );
			buffer.open( IO_WriteOnly );
			QImageIO iio( &buffer, "JPEG" );
			iio.setImage( ( *recipe_it ).photo.convertToImage() );
			iio.write();
			//( *recipe_it ).photo.save( &buffer, "JPEG" ); don't need QImageIO in QT 3.2

			xml += KCodecs::base64Encode( data, true );

			xml += "]]></pic>\n";
		}
		xml += "</pictures>\n";
		xml += "<category>\n";

		for ( ElementList::const_iterator cat_it = ( *recipe_it ).categoryList.begin(); cat_it != ( *recipe_it ).categoryList.end(); ++cat_it )
			xml += "<cat>" + QStyleSheet::escape( ( *cat_it ).name.utf8() ) + "</cat>\n";

		xml += "</category>\n";
		xml += "<yield>";
		xml += "<amount>";
		if ( ( *recipe_it ).yield.amount_offset < 1e-10 ) {
			xml += QString::number( ( *recipe_it ).yield.amount );
		}
		else {
			xml += "<min>"+QString::number( ( *recipe_it ).yield.amount )+"</min>";
			xml += "<max>"+QString::number( ( *recipe_it ).yield.amount + ( *recipe_it ).yield.amount_offset )+"</max>";
		}
		xml += "</amount>";
		xml += "<type>"+( *recipe_it ).yield.type+"</type>";
		xml += "</yield>\n";
		xml += "<preparation-time>";
		xml += ( *recipe_it ).prepTime.toString( "hh:mm" );
		xml += "</preparation-time>\n";
		xml += "</krecipes-description>\n";
		xml += "<krecipes-ingredients>\n";

		IngredientList list_copy = ( *recipe_it ).ingList;
		for ( IngredientList group_list = list_copy.firstGroup(); group_list.count() != 0; group_list = list_copy.nextGroup() ) {
			QString group = group_list[ 0 ].group; //just use the first's name... they're all the same
			if ( !group.isEmpty() )
				xml += "<ingredient-group name=\"" + QStyleSheet::escape(group.utf8()) + "\">\n";

			for ( IngredientList::const_iterator ing_it = group_list.begin(); ing_it != group_list.end(); ++ing_it ) {
				xml += "<ingredient>\n";
				xml += "<name>" + QStyleSheet::escape( ( *ing_it ).name.utf8() ) + "</name>\n";
				xml += "<amount>";
				if ( ( *ing_it ).amount_offset < 1e-10 ) {
					xml += QString::number( ( *ing_it ).amount );
				}
				else {
					xml += "<min>"+QString::number( ( *ing_it ).amount )+"</min>";
					xml += "<max>"+QString::number( ( *ing_it ).amount + ( *ing_it ).amount_offset )+"</max>";
				}
				xml += "</amount>\n";
				QString unit_str = ( ( *ing_it ).amount+( *ing_it ).amount_offset > 1 ) ? ( *ing_it ).units.plural : ( *ing_it ).units.name;
				xml += "<unit>" + QStyleSheet::escape( unit_str.utf8() ) + "</unit>\n";
				if ( ( *ing_it ).prepMethodList.count() > 0 )
					xml += "<prep>" + QStyleSheet::escape( ( *ing_it ).prepMethodList.join(",").utf8() ) + "</prep>\n";
				xml += "</ingredient>\n";
			}

			if ( !group.isEmpty() )
				xml += "</ingredient-group>\n";
		}

		/// @todo add ingredient properties

		xml += "</krecipes-ingredients>\n";
		xml += "<krecipes-instructions>\n";
		xml += QStyleSheet::escape( ( *recipe_it ).instructions.utf8() );
		xml += "</krecipes-instructions>\n";
		xml += "</krecipes-recipe>\n";
	}

	return xml;
}

void KreExporter::createCategoryStructure( QString &xml, const RecipeList &recipes )
{
	QValueList<int> categoriesUsed;
	for ( RecipeList::const_iterator recipe_it = recipes.begin(); recipe_it != recipes.end(); ++recipe_it ) {
		for ( ElementList::const_iterator cat_it = ( *recipe_it ).categoryList.begin(); cat_it != ( *recipe_it ).categoryList.end(); ++cat_it ) {
			if ( categoriesUsed.find( ( *cat_it ).id ) == categoriesUsed.end() )
				categoriesUsed << ( *cat_it ).id;
		}
	}

	if ( !categoriesUsed.empty() ) {
		//only keep the relevant category structure
		removeIfUnused( categoriesUsed, categories );

		xml += "<krecipes-category-structure>\n";
		writeCategoryStructure( xml, categories );
		xml += "</krecipes-category-structure>\n";
	}
}

bool KreExporter::removeIfUnused( const QValueList<int> &cat_ids, CategoryTree *parent, bool parent_should_show )
{
	for ( CategoryTree * it = parent->firstChild(); it; it = it->nextSibling() ) {
		if ( cat_ids.find( it->category.id ) != cat_ids.end() ) {
			parent_should_show = true;
			removeIfUnused( cat_ids, it, true ); //still recurse, but doesn't affect 'parent'
		}
		else {
			bool result = removeIfUnused( cat_ids, it );
			if ( parent_should_show == false )
				parent_should_show = result;
		}
	}

	if ( !parent_should_show && parent->category.id != -1 ) {
		//FIXME: CategoryTree is broken when deleting items
		//delete parent;

		parent->category.id = -2; //temporary workaround
	}

	return parent_should_show;
}

void KreExporter::writeCategoryStructure( QString &xml, const CategoryTree *categoryTree )
{
	if ( categoryTree->category.id != -2 ) {
		if ( categoryTree->category.id != -1 )
			xml += "<category name=\"" + QStyleSheet::escape( categoryTree->category.name.utf8() ).replace("\"",""") + "\">\n";

		for ( CategoryTree * child_it = categoryTree->firstChild(); child_it; child_it = child_it->nextSibling() ) {
			writeCategoryStructure( xml, child_it );
		}

		if ( categoryTree->category.id != -1 )
			xml += "</category>\n";
	}
}

<|endoftext|>


<commit_before>#pragma once

#include <stdexcept>
#include <variant>
#include <string>
#include <string_view>
#include <vector>
#include <iostream>
#include <cassert>

#include "acmacs-base/float.hh"
#include "acmacs-base/filesystem.hh"

// ----------------------------------------------------------------------

namespace rjson
{
    namespace implementation { class NumberHandler; }

    class value;

    class string
    {
     public:
        inline string(std::string aData) : mData{aData} {}
        inline string(const char* aData) : mData{aData} {}
        inline std::string to_json() const { return std::string{"\""} + static_cast<std::string>(mData) + "\""; }
        inline operator std::string() const { return mData; }
        inline string& operator=(std::string aSrc) { mData = aSrc; return *this; }
        inline bool operator==(const std::string aToCompare) const { return mData == aToCompare; }
        inline bool operator==(const string& aToCompare) const { return mData == aToCompare.mData; }

     private:
        std::string mData;
    };

    class boolean
    {
     public:
        inline boolean(bool aValue) : mValue{aValue} {}
        inline std::string to_json() const { return mValue ? "true" : "false"; }
        inline operator bool() const { return mValue; }
        inline boolean& operator=(bool aSrc) { mValue = aSrc; return *this; }

     private:
        bool mValue;
    };

    class null
    {
     public:
        inline null() {}
        inline std::string to_json() const { return "null"; }
    };

    class number
    {
     public:
        inline std::string to_json() const { return mValue; } // { return double_to_string(mValue); }
        inline operator double() const { return std::stod(mValue); } // { return mValue; }
        inline number& operator=(double aSrc) { mValue = double_to_string(aSrc); return *this; }

     private:
        inline number(std::string_view&& aData) : mValue{aData} {} // mValue{std::stod(static_cast<std::string>(aData))} {}

          // double mValue;
        std::string mValue;

        friend class implementation::NumberHandler;
    };

    class integer
    {
     public:
        inline std::string to_json() const { return mValue; } // { return std::to_string(mValue); }
        inline operator double() const { return std::stod(mValue); } // { return mValue; }
        inline operator long() const { return std::stol(mValue); } // { return mValue; }
        inline integer& operator=(long aSrc) { mValue = std::to_string(aSrc); return *this; }

     private:
        inline integer(std::string_view&& aData) : mValue{aData} {} // mValue{std::stol(static_cast<std::string>(aData))} {}

          // long mValue;
        std::string mValue;

        friend class implementation::NumberHandler;
    };

    class object
    {
     public:
        std::string to_json() const;

        void insert(value&& aKey, value&& aValue);

          // returns reference to the value at the passed key.
          // if key not found, inserts aDefault with the passed key and returns reference to the inserted
        value& get_ref(std::string aKey, value&& aDefault);
        void set_field(std::string aKey, value&& aValue);

     private:
        std::vector<std::pair<string, value>> mContent;
    };

    class array
    {
     public:
        std::string to_json() const;

        void insert(value&& aValue);

     private:
        std::vector<value> mContent;
    };

    namespace implementation
    {
        template <typename F> struct content_type;
        template <> struct content_type<double> { using type = rjson::number; };
        template <> struct content_type<long> { using type = rjson::integer; };
        template <> struct content_type<int> { using type = rjson::integer; };
        template <> struct content_type<bool> { using type = rjson::boolean; };
        template <> struct content_type<std::string> { using type = rjson::string; };
    }

    using value_base = std::variant<null, object, array, string, integer, number, boolean>; // null must be the first alternative, it is the default value;

    class value : public value_base
    {
     public:
        using value_base::operator=;
        using value_base::value_base;
        inline value(const value&) = default; // gcc7 wants this, otherwise it is deleted
        inline value& operator=(const value&) = default; // gcc7 wants this, otherwise it is deleted

          // returns reference to the value at the passed key.
          // if key not found, inserts aDefault with the passed key and returns reference to the inserted
          // if this is not an object, throws  std::bad_variant_access
        inline value& get_ref(std::string aKey, value&& aDefault)
            {
                return std::get<object>(*this).get_ref(aKey, std::forward<value>(aDefault));
            }

        template <typename F> inline std::decay_t<F> get_field(std::string aFieldName, F&& aDefaultValue)
            {
                using type = typename implementation::content_type<std::decay_t<F>>::type;
                return std::get<type>(get_ref(aFieldName, std::forward<value>(aDefaultValue)));
            }

        template <typename F> inline void set_field(std::string aFieldName, F&& aValue)
            {
                std::get<object>(*this).set_field(aFieldName, std::forward<value>(aValue));
            }

        std::string to_json() const;
    };

      // ----------------------------------------------------------------------

    class field_container
    {
     public:
        inline void use_json(value& aData) { mData = &aData; }
        inline operator value&() { assert(mData); return *mData; }
        inline operator const value&() const { assert(mData); return *mData; }
        inline std::string json() const { return static_cast<const value&>(*this).to_json(); }

     private:
        mutable value* mData = nullptr;
    };

    template <typename FValue> class field_get_set
    {
     public:
        inline field_get_set(field_container* aContainer, std::string aFieldName, FValue&& aDefault) : mContainer{*aContainer}, mFieldName{aFieldName}, mDefault{std::move(aDefault)} {}
        inline operator FValue() const { return static_cast<value&>(mContainer).get_field(mFieldName, mDefault); } // static_cast to non-const because we need to set to mDefault
        inline field_get_set<FValue>& operator = (FValue&& aValue) { static_cast<value&>(mContainer).set_field(mFieldName, std::forward<FValue>(aValue)); return *this; }
        inline field_get_set<FValue>& operator = (const field_get_set<FValue>& aSource) { return operator=(static_cast<FValue>(aSource)); }

     private:
        field_container& mContainer;
        std::string mFieldName;
        FValue mDefault;
    };

      // ----------------------------------------------------------------------

    class Error : public std::exception
    {
     public:
        // inline Error(size_t aLine, size_t aColumn, std::string aMessage)
        //     : mMessage{std::to_string(aLine) + ":" + std::to_string(aColumn) + ": " + aMessage} //, mLine{aLine}, mColumn{aColumn}
        //     {}

        inline Error(size_t aLine, size_t aColumn, std::string&& aMessage)
            : mMessage{std::to_string(aLine) + ":" + std::to_string(aColumn) + ": " + std::move(aMessage)} //, mLine{aLine}, mColumn{aColumn}
            {}

        inline const char* what() const noexcept override { return mMessage.c_str(); }

     private:
        std::string mMessage;
          //size_t mLine, mColumn;

    }; // class Error

    value parse_string(std::string aJsonData);
    value parse_file(std::string aFilename);

} // namespace rjson

// ----------------------------------------------------------------------
// gcc-7 support
// ----------------------------------------------------------------------

#if __GNUC__ == 7
namespace std
{
      // gcc 7.2 wants those, if we derive from std::variant
    template<> struct variant_size<rjson::value> : variant_size<rjson::value_base> {};
    template<size_t _Np> struct variant_alternative<_Np, rjson::value> : variant_alternative<_Np, rjson::value_base> {};
}
#endif

// ----------------------------------------------------------------------
// inline
// ----------------------------------------------------------------------

namespace rjson
{
    inline void object::insert(value&& aKey, value&& aValue)
    {
        mContent.emplace_back(std::get<rjson::string>(aKey), aValue);
    }

    inline value& object::get_ref(std::string aKey, value&& aDefault)
    {
        auto found = std::find_if(std::begin(mContent), std::end(mContent), [&aKey](const auto& entry) { return entry.first == aKey; });
        if (found == std::end(mContent)) {
              // std::cerr << "DEBUG: object::get_ref: not found: " << aKey << ' ' << to_json() << " default:" << aDefault.to_json() << '\n';
            return mContent.emplace_back(std::move(aKey), std::forward<value>(aDefault)).second;
        }
        else {
              // std::d::cerr << "DEBUG: object::get_ref: found: " << aKey << ' ' << found->second.to_json() << '\n';
            return found->second;
        }
    }

    inline void object::set_field(std::string aKey, value&& aValue)
    {
        auto found = std::find_if(std::begin(mContent), std::end(mContent), [&aKey](const auto& entry) { return entry.first == aKey; });
        if (found == std::end(mContent)) {
            mContent.emplace_back(std::move(aKey), std::forward<value>(aValue));
        }
        else {
            found->second = std::forward<value>(aValue);
        }
    }

      // ----------------------------------------------------------------------

    inline void array::insert(value&& aValue)
    {
        mContent.push_back(std::move(aValue));
    }

      // ----------------------------------------------------------------------

    inline std::string value::to_json() const
    {
        return std::visit([](auto&& arg) -> std::string { return arg.to_json(); }, *this);
    }
}

// ----------------------------------------------------------------------

inline std::ostream& operator<<(std::ostream& out, const rjson::value& aValue)
{
    return out << aValue.to_json();
}

template <typename FValue> inline std::ostream& operator<<(std::ostream& out, const rjson::field_get_set<FValue>& aValue)
{
    return out << static_cast<FValue>(aValue);
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>rjson development<commit_after>#pragma once

#include <stdexcept>
#include <variant>
#include <string>
#include <string_view>
#include <vector>
#include <iostream>
#include <cassert>

#include "acmacs-base/float.hh"
#include "acmacs-base/filesystem.hh"

// ----------------------------------------------------------------------

namespace rjson
{
    namespace implementation { class NumberHandler; }

    class value;

    class string
    {
     public:
        inline string(std::string aData) : mData{aData} {}
        inline string(const char* aData) : mData{aData} {}
        inline std::string to_json() const { return std::string{"\""} + static_cast<std::string>(mData) + "\""; }
        inline operator std::string() const { return mData; }
        inline string& operator=(std::string aSrc) { mData = aSrc; return *this; }
        inline bool operator==(const std::string aToCompare) const { return mData == aToCompare; }
        inline bool operator==(const string& aToCompare) const { return mData == aToCompare.mData; }

     private:
        std::string mData;
    };

    class boolean
    {
     public:
        inline boolean(bool aValue) : mValue{aValue} {}
        inline std::string to_json() const { return mValue ? "true" : "false"; }
        inline operator bool() const { return mValue; }
        inline boolean& operator=(bool aSrc) { mValue = aSrc; return *this; }

     private:
        bool mValue;
    };

    class null
    {
     public:
        inline null() {}
        inline std::string to_json() const { return "null"; }
    };

    class number
    {
     public:
        inline number(double aSrc) : mValue{double_to_string(aSrc)} {}
        inline number& operator=(double aSrc) { mValue = double_to_string(aSrc); return *this; }
        inline std::string to_json() const { return mValue; } // { return double_to_string(mValue); }
        inline operator double() const { return std::stod(mValue); } // { return mValue; }

     private:
        inline number(std::string_view&& aData) : mValue{aData} {} // mValue{std::stod(static_cast<std::string>(aData))} {}

          // double mValue;
        std::string mValue;

        friend class implementation::NumberHandler;
    };

    class integer
    {
     public:
        inline integer(long aSrc) : mValue{std::to_string(aSrc)} {}
        inline integer& operator=(long aSrc) { mValue = std::to_string(aSrc); return *this; }
        inline std::string to_json() const { return mValue; } // { return std::to_string(mValue); }
        inline operator double() const { return std::stod(mValue); } // { return mValue; }
        inline operator long() const { return std::stol(mValue); } // { return mValue; }

     private:
        inline integer(std::string_view&& aData) : mValue{aData} {} // mValue{std::stol(static_cast<std::string>(aData))} {}

          // long mValue;
        std::string mValue;

        friend class implementation::NumberHandler;
    };

    class object
    {
     public:
        std::string to_json() const;

        void insert(value&& aKey, value&& aValue);

          // returns reference to the value at the passed key.
          // if key not found, inserts aDefault with the passed key and returns reference to the inserted
        value& get_ref(std::string aKey, value&& aDefault);
        void set_field(std::string aKey, value&& aValue);

     private:
        std::vector<std::pair<string, value>> mContent;
    };

    class array
    {
     public:
        std::string to_json() const;

        void insert(value&& aValue);

     private:
        std::vector<value> mContent;
    };

    namespace implementation
    {
        template <typename F> struct content_type;
        template <> struct content_type<double> { using type = rjson::number; };
        template <> struct content_type<long> { using type = rjson::integer; };
        template <> struct content_type<int> { using type = rjson::integer; };
        template <> struct content_type<bool> { using type = rjson::boolean; };
        template <> struct content_type<std::string> { using type = rjson::string; };
    }

    using value_base = std::variant<null, object, array, string, integer, number, boolean>; // null must be the first alternative, it is the default value;

    class value : public value_base
    {
     public:
        using value_base::operator=;
        using value_base::value_base;
        inline value(const value&) = default; // gcc7 wants this, otherwise it is deleted
        inline value& operator=(const value&) = default; // gcc7 wants this, otherwise it is deleted

          // returns reference to the value at the passed key.
          // if key not found, inserts aDefault with the passed key and returns reference to the inserted
          // if this is not an object, throws  std::bad_variant_access
        inline value& get_ref(std::string aKey, value&& aDefault)
            {
                return std::get<object>(*this).get_ref(aKey, std::forward<value>(aDefault));
            }

        template <typename F> inline std::decay_t<F> get_field(std::string aFieldName, F&& aDefaultValue)
            {
                using rjson_type = typename implementation::content_type<std::decay_t<F>>::type;
                return std::get<rjson_type>(get_ref(aFieldName, rjson_type{std::forward<F>(aDefaultValue)}));
            }

        template <typename F> inline void set_field(std::string aFieldName, F&& aValue)
            {
                using rjson_type = typename implementation::content_type<std::decay_t<F>>::type;
                std::get<object>(*this).set_field(aFieldName, rjson_type{std::forward<F>(aValue)});
            }

        std::string to_json() const;
    };

      // ----------------------------------------------------------------------

    class field_container
    {
     public:
        inline void use_json(value& aData) { mData = &aData; }
        inline operator value&() { assert(mData); return *mData; }
        inline operator const value&() const { assert(mData); return *mData; }
        inline std::string to_json() const { return static_cast<const value&>(*this).to_json(); }

     private:
        mutable value* mData = nullptr;
    };

    template <typename FValue> class field_get_set
    {
     public:
        inline field_get_set(field_container* aContainer, std::string aFieldName, FValue&& aDefault) : mContainer{*aContainer}, mFieldName{aFieldName}, mDefault{std::move(aDefault)} {}
        inline operator FValue() const { return static_cast<value&>(mContainer).get_field(mFieldName, mDefault); } // static_cast to non-const because we need to set to mDefault
        inline field_get_set<FValue>& operator = (FValue&& aValue) { static_cast<value&>(mContainer).set_field(mFieldName, std::forward<FValue>(aValue)); return *this; }
        inline field_get_set<FValue>& operator = (const field_get_set<FValue>& aSource) { return operator=(static_cast<FValue>(aSource)); }

     private:
        field_container& mContainer;
        std::string mFieldName;
        FValue mDefault;
    };

      // ----------------------------------------------------------------------

    class Error : public std::exception
    {
     public:
        // inline Error(size_t aLine, size_t aColumn, std::string aMessage)
        //     : mMessage{std::to_string(aLine) + ":" + std::to_string(aColumn) + ": " + aMessage} //, mLine{aLine}, mColumn{aColumn}
        //     {}

        inline Error(size_t aLine, size_t aColumn, std::string&& aMessage)
            : mMessage{std::to_string(aLine) + ":" + std::to_string(aColumn) + ": " + std::move(aMessage)} //, mLine{aLine}, mColumn{aColumn}
            {}

        inline const char* what() const noexcept override { return mMessage.c_str(); }

     private:
        std::string mMessage;
          //size_t mLine, mColumn;

    }; // class Error

    value parse_string(std::string aJsonData);
    value parse_file(std::string aFilename);

} // namespace rjson

// ----------------------------------------------------------------------
// gcc-7 support
// ----------------------------------------------------------------------

#if __GNUC__ == 7
namespace std
{
      // gcc 7.2 wants those, if we derive from std::variant
    template<> struct variant_size<rjson::value> : variant_size<rjson::value_base> {};
    template<size_t _Np> struct variant_alternative<_Np, rjson::value> : variant_alternative<_Np, rjson::value_base> {};
}
#endif

// ----------------------------------------------------------------------
// inline
// ----------------------------------------------------------------------

namespace rjson
{
    inline void object::insert(value&& aKey, value&& aValue)
    {
        mContent.emplace_back(std::get<rjson::string>(aKey), aValue);
    }

    inline value& object::get_ref(std::string aKey, value&& aDefault)
    {
        auto found = std::find_if(std::begin(mContent), std::end(mContent), [&aKey](const auto& entry) { return entry.first == aKey; });
        if (found == std::end(mContent)) {
              // std::cerr << "DEBUG: object::get_ref: not found: " << aKey << ' ' << to_json() << " default:" << aDefault.to_json() << '\n';
            return mContent.emplace_back(std::move(aKey), std::forward<value>(aDefault)).second;
        }
        else {
            // std::cerr << "DEBUG: object::get_ref: found: " << aKey << ' ' << found->second.to_json() << '\n';
            return found->second;
        }
    }

    inline void object::set_field(std::string aKey, value&& aValue)
    {
        auto found = std::find_if(std::begin(mContent), std::end(mContent), [&aKey](const auto& entry) { return entry.first == aKey; });
        if (found == std::end(mContent)) {
            mContent.emplace_back(std::move(aKey), std::forward<value>(aValue));
        }
        else {
            found->second = std::forward<value>(aValue);
        }
    }

      // ----------------------------------------------------------------------

    inline void array::insert(value&& aValue)
    {
        mContent.push_back(std::move(aValue));
    }

      // ----------------------------------------------------------------------

    inline std::string value::to_json() const
    {
        return std::visit([](auto&& arg) -> std::string { return arg.to_json(); }, *this);
    }
}

// ----------------------------------------------------------------------

inline std::ostream& operator<<(std::ostream& out, const rjson::value& aValue)
{
    return out << aValue.to_json();
}

template <typename FValue> inline std::ostream& operator<<(std::ostream& out, const rjson::field_get_set<FValue>& aValue)
{
    return out << static_cast<FValue>(aValue);
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 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_ENGINE_MeshSplittingEngine_INL
#define SOFA_COMPONENT_ENGINE_MeshSplittingEngine_INL

#include "MeshSplittingEngine.h"

namespace sofa
{

namespace component
{

namespace engine
{

template <class container>
inline void parseIndices(vector<unsigned int>& pairs, const container& indices, const unsigned int parentIndex)
{
    for(size_t i=0;i<indices.size();++i)
        if(2*indices[i]<pairs.size())
            pairs[2*indices[i]]=parentIndex;
}

template <class container1,class container2>
inline void parseIndices(vector<unsigned int>& pairs, const container1& indices,const container2& cells, const unsigned int parentIndex)
{
    for(size_t i=0;i<indices.size();++i)
        for(size_t j=0;j<cells[indices[i]].size();++j)
            if(2*cells[indices[i]][j]<pairs.size())
                pairs[2*cells[indices[i]][j]]=parentIndex;
}

template <class DataTypes>
void MeshSplittingEngine<DataTypes>::update()
{
    updateAllInputsIfDirty();
    cleanDirty();

    helper::ReadAccessor<Data< SeqPositions > > i_pos(this->inputPosition);
    const size_t& nb = nbInputs.getValue();

    helper::WriteOnlyAccessor<Data< vector<unsigned int> > > indPairs(this->indexPairs);
    indPairs.resize(2*i_pos.size());
    for(size_t i=0;i<i_pos.size();++i) indPairs[2*i]=nb; // assign to remaining sub mesh

    // get parent of each child
    for(size_t i=0;i<nb;++i)
    {
        parseIndices(indPairs.wref(), indices[i]->getValue(), i);
        parseIndices(indPairs.wref(), edgeIndices[i]->getValue(), inputEdges.getValue(), i);
        parseIndices(indPairs.wref(), triangleIndices[i]->getValue(), inputTriangles.getValue(), i);
        parseIndices(indPairs.wref(), quadIndices[i]->getValue(), inputQuads.getValue(), i);
        parseIndices(indPairs.wref(), tetrahedronIndices[i]->getValue(), inputTets.getValue(), i);
        parseIndices(indPairs.wref(), hexahedronIndices[i]->getValue(), inputHexa.getValue(), i);
    }

    // add positions
    std::vector<SeqPositions*> o_pos(nb+1);
    for(size_t i=0;i<nb+1;++i) { o_pos[i]=position[i]->beginWriteOnly(); o_pos[i]->clear(); }

    for(size_t i=0;i<i_pos.size();++i)
    {
        indPairs[2*i+1]=o_pos[indPairs[2*i]]->size();
        o_pos[indPairs[2*i]]->push_back(i_pos[i]);
    }
    for(size_t i=0;i<nb+1;++i) position[i]->endEdit();

    if(this->f_printLog.getValue())    std::cout<<this->name<<":"<<"updated"<<std::endl;
}

#if defined(SOFA_EXTERN_TEMPLATE) && !defined(SOFA_COMPONENT_ENGINE_MeshSplittingEngine_CPP)
#ifndef SOFA_FLOAT
extern template class SOFA_ENGINE_API MeshSplittingEngine<defaulttype::Vec3dTypes>;
#endif //SOFA_FLOAT
#ifndef SOFA_DOUBLE
extern template class SOFA_ENGINE_API MeshSplittingEngine<defaulttype::Vec3fTypes>;
#endif //SOFA_DOUBLE
#endif

} // namespace engine

} // namespace component

} // namespace sofa

#endif
<commit_msg>MeshSplittingEngine: put ROI priority in right order<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 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_ENGINE_MeshSplittingEngine_INL
#define SOFA_COMPONENT_ENGINE_MeshSplittingEngine_INL

#include "MeshSplittingEngine.h"

namespace sofa
{

namespace component
{

namespace engine
{

template <class container>
inline void parseIndices(vector<unsigned int>& pairs, const container& indices, const unsigned int parentIndex)
{
    for(size_t i=0;i<indices.size();++i)
        if(2*indices[i]<pairs.size())
            pairs[2*indices[i]]=parentIndex;
}

template <class container1,class container2>
inline void parseIndices(vector<unsigned int>& pairs, const container1& indices,const container2& cells, const unsigned int parentIndex)
{
    for(size_t i=0;i<indices.size();++i)
        for(size_t j=0;j<cells[indices[i]].size();++j)
            if(2*cells[indices[i]][j]<pairs.size())
                pairs[2*cells[indices[i]][j]]=parentIndex;
}

template <class DataTypes>
void MeshSplittingEngine<DataTypes>::update()
{
    updateAllInputsIfDirty();
    cleanDirty();

    helper::ReadAccessor<Data< SeqPositions > > i_pos(this->inputPosition);
    const size_t& nb = nbInputs.getValue();

    helper::WriteOnlyAccessor<Data< vector<unsigned int> > > indPairs(this->indexPairs);
    indPairs.resize(2*i_pos.size());
    for(size_t i=0;i<i_pos.size();++i) indPairs[2*i]=nb; // assign to remaining sub mesh

    // get parent of each child
    for(int i=nb-1;i>=0;--i) // use reverse order to prioritize the first ROIs
    {
        parseIndices(indPairs.wref(), indices[i]->getValue(), i);
        parseIndices(indPairs.wref(), edgeIndices[i]->getValue(), inputEdges.getValue(), i);
        parseIndices(indPairs.wref(), triangleIndices[i]->getValue(), inputTriangles.getValue(), i);
        parseIndices(indPairs.wref(), quadIndices[i]->getValue(), inputQuads.getValue(), i);
        parseIndices(indPairs.wref(), tetrahedronIndices[i]->getValue(), inputTets.getValue(), i);
        parseIndices(indPairs.wref(), hexahedronIndices[i]->getValue(), inputHexa.getValue(), i);
    }

    // add positions
    std::vector<SeqPositions*> o_pos(nb+1);
    for(size_t i=0;i<nb+1;++i) { o_pos[i]=position[i]->beginWriteOnly(); o_pos[i]->clear(); }

    for(size_t i=0;i<i_pos.size();++i)
    {
        indPairs[2*i+1]=o_pos[indPairs[2*i]]->size();
        o_pos[indPairs[2*i]]->push_back(i_pos[i]);
    }
    for(size_t i=0;i<nb+1;++i) position[i]->endEdit();

    if(this->f_printLog.getValue())    std::cout<<this->name<<":"<<"updated"<<std::endl;
}

#if defined(SOFA_EXTERN_TEMPLATE) && !defined(SOFA_COMPONENT_ENGINE_MeshSplittingEngine_CPP)
#ifndef SOFA_FLOAT
extern template class SOFA_ENGINE_API MeshSplittingEngine<defaulttype::Vec3dTypes>;
#endif //SOFA_FLOAT
#ifndef SOFA_DOUBLE
extern template class SOFA_ENGINE_API MeshSplittingEngine<defaulttype::Vec3fTypes>;
#endif //SOFA_DOUBLE
#endif

} // namespace engine

} // namespace component

} // namespace sofa

#endif
<|endoftext|>


<commit_before>/**
 *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
 *   University of Wisconsin—Madison.
 *
 *   Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 **/

#ifndef QUICKSTEP_UTILITY_TEMPLATE_UTIL_HPP_
#define QUICKSTEP_UTILITY_TEMPLATE_UTIL_HPP_

#include <utility>

namespace quickstep {

/** \addtogroup Utility
 *  @{
 */

/**
 * @brief Represents a compile-time sequence of integers.
 *
 * Seq is defined here for C++11 compatibility. For C++14 and above,
 * std::integer_sequence can be used to achieve the same functionality.
 */
template<size_t ...>
struct Seq {};

/**
 * @brief The helper class for creating Seq. GenSeq<N>::type is equivalent to
 *        Seq<1,2,...,N>.
 *
 * GenSeq is defined here for C++11 compatibility. For C++14 and above,
 * std::make_interger_sequence can be used to achieve the same functionality.
 */
template<size_t N, size_t ...S>
struct GenSeq : GenSeq<N-1, N-1, S...> {};

template<size_t ...S>
struct GenSeq<0, S...> {
  typedef Seq<S...> type;
};

/**
 * @brief Final step of CreateBoolInstantiatedInstance. Now all bool_values are
 *        ready. Instantiate the template and create (i.e. new) an instance.
 */
template <template <bool ...> class T, class ReturnT,
          bool ...bool_values, size_t ...i,
          typename Tuple>
inline ReturnT* CreateBoolInstantiatedInstanceInner(Tuple&& args, Seq<i...>&& indices) {
  return new T<bool_values...>(std::get<i>(std::forward<Tuple>(args))...);
}

/**
 * @brief Edge case of the recursive CreateBoolInstantiatedInstance function
 *        when all bool variables have been branched and replaced with compile-time
 *        bool constants.
 */
template <template <bool ...> class T, class ReturnT,
          bool ...bool_values,
          typename ArgsTuple>
inline ReturnT* CreateBoolInstantiatedInstance(ArgsTuple&& args) {
  // Note that the constructor arguments have been forwarded as a tuple (args).
  // Here we generate a compile-time index sequence (i.e. typename GenSeq<n_args>::type())
  // for the tuple, so that the tuple can be unpacked as a sequence of constructor
  // parameters in CreateBoolInstantiatedInstanceInner.
  constexpr std::size_t n_args = std::tuple_size<ArgsTuple>::value;
  return CreateBoolInstantiatedInstanceInner<T, ReturnT, bool_values...>(
      std::forward<ArgsTuple>(args), typename GenSeq<n_args>::type());
}

/**
 * @brief A helper function for creating bool branched templates.
 *
 * The scenario for using this helper function is that, suppose we have a class
 * where all template parameters are bools:
 * --
 * template <bool c1, bool c2, bool c3>
 * class SomeClass : BaseClass {
 *   // This simple function will be invoked in computationally-intensive loops.
 *   inline SomeType someSimpleFunction(...) {
 *     if (c1) {
 *       doSomeThing1();
 *     }
 *     if (c2) {
 *       doSomeThing2();
 *     }
 *     if (c3) {
 *       doSomeThing3();
 *     }
 *   }
 * };
 * --
 * Typically, this bool-paramterized template is for performance consideration.
 * That is, we would like to make a copy of code for each configuration of bool
 * values, so that there will be no branchings in someSimpleFunction().
 *
 * The problem is that, to conditionally instantiate the template, given bool
 * variables c1, c2, c3, we have to do something like this:
 * --
 * if (c1) {
 *   if (c2) {
 *     if (c3) {
 *       return new SomeClass<true, true, true>(some_args...);
 *     } else {
 *       return new SomeClass<true, true, false>(some_args...);
 *     }
 *   } else {
 *     if (c3) {
 *       return new SomeClass<true, false, true>(some_args...);
 *     } else {
 *       return new SomeClass<true, false, false>(some_args...);
 *     }
 * } else {
 *   ...
 * }
 * --
 * Then there will be power(2,N) branches if the template has N bool parameters,
 * making it tedious to do the instantiating.
 *
 * Now, this helper function can achieve the branched instantiation in one
 * statement as:
 * --
 * return CreateBoolInstantiatedInstance<SomeClass,BaseClass>(
 *     std::forward_as_tuple(some_args...), c1, c2, c3);
 * --
 */
template <template <bool ...> class T, class ReturnT,
          bool ...bool_values, typename ...Bools,
          typename ArgsTuple>
inline ReturnT* CreateBoolInstantiatedInstance(
    ArgsTuple&& args, bool tparam, Bools ...rest_tparams) {
  if (tparam) {
    return CreateBoolInstantiatedInstance<T, ReturnT, bool_values..., true>(
        std::forward<ArgsTuple>(args), rest_tparams...);
  } else {
    return CreateBoolInstantiatedInstance<T, ReturnT, bool_values..., false>(
        std::forward<ArgsTuple>(args), rest_tparams...);
  }
}

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_UTILITY_TEMPLATE_UTIL_HPP_
<commit_msg>std_size_t<commit_after>/**
 *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
 *   University of Wisconsin—Madison.
 *
 *   Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 **/

#ifndef QUICKSTEP_UTILITY_TEMPLATE_UTIL_HPP_
#define QUICKSTEP_UTILITY_TEMPLATE_UTIL_HPP_

#include <utility>

namespace quickstep {

/** \addtogroup Utility
 *  @{
 */

/**
 * @brief Represents a compile-time sequence of integers.
 *
 * Seq is defined here for C++11 compatibility. For C++14 and above,
 * std::integer_sequence can be used to achieve the same functionality.
 */
template<std::size_t ...>
struct Seq {};

/**
 * @brief The helper class for creating Seq. GenSeq<N>::type is equivalent to
 *        Seq<1,2,...,N>.
 *
 * GenSeq is defined here for C++11 compatibility. For C++14 and above,
 * std::make_interger_sequence can be used to achieve the same functionality.
 */
template<std::size_t N, std::size_t ...S>
struct GenSeq : GenSeq<N-1, N-1, S...> {};

template<std::size_t ...S>
struct GenSeq<0, S...> {
  typedef Seq<S...> type;
};

/**
 * @brief Final step of CreateBoolInstantiatedInstance. Now all bool_values are
 *        ready. Instantiate the template and create (i.e. new) an instance.
 */
template <template <bool ...> class T, class ReturnT,
          bool ...bool_values, std::size_t ...i,
          typename Tuple>
inline ReturnT* CreateBoolInstantiatedInstanceInner(Tuple&& args, Seq<i...>&& indices) {
  return new T<bool_values...>(std::get<i>(std::forward<Tuple>(args))...);
}

/**
 * @brief Edge case of the recursive CreateBoolInstantiatedInstance function
 *        when all bool variables have been branched and replaced with compile-time
 *        bool constants.
 */
template <template <bool ...> class T, class ReturnT,
          bool ...bool_values,
          typename ArgsTuple>
inline ReturnT* CreateBoolInstantiatedInstance(ArgsTuple&& args) {
  // Note that the constructor arguments have been forwarded as a tuple (args).
  // Here we generate a compile-time index sequence (i.e. typename GenSeq<n_args>::type())
  // for the tuple, so that the tuple can be unpacked as a sequence of constructor
  // parameters in CreateBoolInstantiatedInstanceInner.
  constexpr std::size_t n_args = std::tuple_size<ArgsTuple>::value;
  return CreateBoolInstantiatedInstanceInner<T, ReturnT, bool_values...>(
      std::forward<ArgsTuple>(args), typename GenSeq<n_args>::type());
}

/**
 * @brief A helper function for creating bool branched templates.
 *
 * The scenario for using this helper function is that, suppose we have a class
 * where all template parameters are bools:
 * --
 * template <bool c1, bool c2, bool c3>
 * class SomeClass : BaseClass {
 *   // This simple function will be invoked in computationally-intensive loops.
 *   inline SomeType someSimpleFunction(...) {
 *     if (c1) {
 *       doSomeThing1();
 *     }
 *     if (c2) {
 *       doSomeThing2();
 *     }
 *     if (c3) {
 *       doSomeThing3();
 *     }
 *   }
 * };
 * --
 * Typically, this bool-paramterized template is for performance consideration.
 * That is, we would like to make a copy of code for each configuration of bool
 * values, so that there will be no branchings in someSimpleFunction().
 *
 * The problem is that, to conditionally instantiate the template, given bool
 * variables c1, c2, c3, we have to do something like this:
 * --
 * if (c1) {
 *   if (c2) {
 *     if (c3) {
 *       return new SomeClass<true, true, true>(some_args...);
 *     } else {
 *       return new SomeClass<true, true, false>(some_args...);
 *     }
 *   } else {
 *     if (c3) {
 *       return new SomeClass<true, false, true>(some_args...);
 *     } else {
 *       return new SomeClass<true, false, false>(some_args...);
 *     }
 * } else {
 *   ...
 * }
 * --
 * Then there will be power(2,N) branches if the template has N bool parameters,
 * making it tedious to do the instantiating.
 *
 * Now, this helper function can achieve the branched instantiation in one
 * statement as:
 * --
 * return CreateBoolInstantiatedInstance<SomeClass,BaseClass>(
 *     std::forward_as_tuple(some_args...), c1, c2, c3);
 * --
 */
template <template <bool ...> class T, class ReturnT,
          bool ...bool_values, typename ...Bools,
          typename ArgsTuple>
inline ReturnT* CreateBoolInstantiatedInstance(
    ArgsTuple&& args, bool tparam, Bools ...rest_tparams) {
  if (tparam) {
    return CreateBoolInstantiatedInstance<T, ReturnT, bool_values..., true>(
        std::forward<ArgsTuple>(args), rest_tparams...);
  } else {
    return CreateBoolInstantiatedInstance<T, ReturnT, bool_values..., false>(
        std::forward<ArgsTuple>(args), rest_tparams...);
  }
}

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_UTILITY_TEMPLATE_UTIL_HPP_
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: imagemgr.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-01-11 14:42:58 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SAL_CONFIG_H_
#include "sal/config.h"
#endif

#ifndef INCLUDED_SFX2_DLLAPI_H
#include "sfx2/dllapi.h"
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif
#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

#include <rtl/ustring.hxx>
#include <vcl/image.hxx>

SFX2_DLLPUBLIC Image SAL_CALL GetImage( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, const ::rtl::OUString& aURL, BOOL bBig, BOOL bHiContrast );
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.288); FILE MERGED 2005/09/05 15:21:25 rt 1.3.288.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: imagemgr.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 16:57:36 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _SAL_CONFIG_H_
#include "sal/config.h"
#endif

#ifndef INCLUDED_SFX2_DLLAPI_H
#include "sfx2/dllapi.h"
#endif

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif
#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

#include <rtl/ustring.hxx>
#include <vcl/image.hxx>

SFX2_DLLPUBLIC Image SAL_CALL GetImage( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, const ::rtl::OUString& aURL, BOOL bBig, BOOL bHiContrast );
<|endoftext|>


<commit_before>/* RTcmix - Copyright (C) 2005  The RTcmix Development Team
	See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
	the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
// Write a basic .rtcmixrc file in the user's home directory.
// -JGG, 7/1/04; rev. for MIDI/audio devices, 7/29/05.

#include <Option.h>
#include <stdio.h>
#include "../src/control/midi/portmidi/pm_common/portmidi.h"

// We make our own warn function so that we don't have to pull in more
// RTcmix code.  This must have the same signature as the real one in
// message.c.	It doesn't print WARNING ***, though.

#include <stdarg.h>

#define BUFSIZE 1024

extern "C" {
void
warn(const char *inst_name, const char *format, ...)
{
	// ignore inst_name

	char		buf[BUFSIZE];
	va_list	args;

	va_start(args, format);
	vsnprintf(buf, BUFSIZE, format, args);
	va_end(args);

	fprintf(stderr, "\n%s\n\n", buf);
}
} // extern "C"

int chooseAudioDevices()
{
	return 0;
}

#if defined(MACOSX) || defined(ALSA)

void makeMIDIChoice(const PmDeviceInfo *info[], const int numDevices,
	const bool input)
{
	const char *direction = input ? "input" : "output";

	printf("\nHere are the names of MIDI %s devices in your system...\n\n"
	       "\tID\tName\n"
	       "----------------------------------------------------------\n",
	       direction);

	for (int id = 0; id < numDevices; id++) {
		if (info[id] != NULL) {
			if ((input && info[id]->input) || (!input && info[id]->output))
				printf("\t%d\t\"%s\"\n", id, info[id]->name);
		}
	}
	printf("\nEnter the ID number of one of the listed devices...\n");
	bool trying = true;
	while (trying) {
		int chosenID;
		if (scanf("%d", &chosenID) == 1) {
			if (chosenID >= 0 && chosenID < numDevices && info[chosenID] != NULL) {
				if (input && info[chosenID]->input) {
					Option::midiInDevice(info[chosenID]->name);
					trying = false;
				}
				else if (!input && info[chosenID]->output) {
					Option::midiOutDevice(info[chosenID]->name);
					trying = false;
				}
			}
			else
				printf("The number you typed was not one of the listed ID "
						 "numbers.  Try again...\n");
		}
		else {
			trying = false;
		}
	}
}

int chooseMIDIDevices()
{
	int status = 0;
	Pm_Initialize();

	const int numdev = Pm_CountDevices();
	const PmDeviceInfo *info[numdev];

	bool hasinputdev = false;
	bool hasoutputdev = false;
	for (int id = 0; id < numdev; id++) {
		info[id] = Pm_GetDeviceInfo(id);
		if (info[id] != NULL) {
			if (info[id]->input)
				hasinputdev = true;
			else if (info[id]->output)
				hasoutputdev = true;
		}
	}

	if (hasinputdev)
		makeMIDIChoice(info, numdev, true);
	else
		printf("NOTE: Your system appears to have no MIDI input devices.\n");

#ifdef NOTYET // XXX we don't support MIDI output yet
	if (hasoutputdev)
		makeMIDIChoice(info, numdev, false);
	else
		printf("NOTE: Your system appears to have no MIDI output devices.\n");
#endif

	Pm_Terminate();
	return status;
}

#else // !defined(MACOSX) && !defined(ALSA)

int chooseMIDIDevices()
{
	printf("NOTE: MIDI not supported on your platform.\n");
	return 0;
}

#endif

int main()
{
	Option::init();

	if (chooseAudioDevices() != 0)
		return -1;
	if (chooseMIDIDevices() != 0)
		return -1;

	if (Option::writeConfigFile(Option::rcName()) != 0)
		return -1;
	printf("Configuration file \"%s\" successfully written.\n",
	                                                Option::rcName());
	return 0;
}

<commit_msg>Comment out warn() -- doesn't appear to be necessary any more.<commit_after>/* RTcmix - Copyright (C) 2005  The RTcmix Development Team
	See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
	the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
// Write a basic .rtcmixrc file in the user's home directory.
// -JGG, 7/1/04; rev. for MIDI/audio devices, 7/29/05.

#include <Option.h>
#include <stdio.h>
#include "../src/control/midi/portmidi/pm_common/portmidi.h"

// FIXME no longer necessary?
#if 0
// We make our own warn function so that we don't have to pull in more
// RTcmix code.  This must have the same signature as the real one in
// message.c.	It doesn't print WARNING ***, though.

#include <stdarg.h>

#define BUFSIZE 1024

extern "C" {
void
warn(const char *inst_name, const char *format, ...)
{
	// ignore inst_name

	char		buf[BUFSIZE];
	va_list	args;

	va_start(args, format);
	vsnprintf(buf, BUFSIZE, format, args);
	va_end(args);

	fprintf(stderr, "\n%s\n\n", buf);
}
} // extern "C"
#endif

int chooseAudioDevices()
{
	return 0;
}

#if defined(MACOSX) || defined(ALSA)

void makeMIDIChoice(const PmDeviceInfo *info[], const int numDevices,
	const bool input)
{
	const char *direction = input ? "input" : "output";

	printf("\nHere are the names of MIDI %s devices in your system...\n\n"
	       "\tID\tName\n"
	       "----------------------------------------------------------\n",
	       direction);

	for (int id = 0; id < numDevices; id++) {
		if (info[id] != NULL) {
			if ((input && info[id]->input) || (!input && info[id]->output))
				printf("\t%d\t\"%s\"\n", id, info[id]->name);
		}
	}
	printf("\nEnter the ID number of one of the listed devices...\n");
	bool trying = true;
	while (trying) {
		int chosenID;
		if (scanf("%d", &chosenID) == 1) {
			if (chosenID >= 0 && chosenID < numDevices && info[chosenID] != NULL) {
				if (input && info[chosenID]->input) {
					Option::midiInDevice(info[chosenID]->name);
					trying = false;
				}
				else if (!input && info[chosenID]->output) {
					Option::midiOutDevice(info[chosenID]->name);
					trying = false;
				}
			}
			else
				printf("The number you typed was not one of the listed ID "
						 "numbers.  Try again...\n");
		}
		else {
			trying = false;
		}
	}
}

int chooseMIDIDevices()
{
	int status = 0;
	Pm_Initialize();

	const int numdev = Pm_CountDevices();
	const PmDeviceInfo *info[numdev];

	bool hasinputdev = false;
	bool hasoutputdev = false;
	for (int id = 0; id < numdev; id++) {
		info[id] = Pm_GetDeviceInfo(id);
		if (info[id] != NULL) {
			if (info[id]->input)
				hasinputdev = true;
			else if (info[id]->output)
				hasoutputdev = true;
		}
	}

	if (hasinputdev)
		makeMIDIChoice(info, numdev, true);
	else
		printf("NOTE: Your system appears to have no MIDI input devices.\n");

#ifdef NOTYET // XXX we don't support MIDI output yet
	if (hasoutputdev)
		makeMIDIChoice(info, numdev, false);
	else
		printf("NOTE: Your system appears to have no MIDI output devices.\n");
#endif

	Pm_Terminate();
	return status;
}

#else // !defined(MACOSX) && !defined(ALSA)

int chooseMIDIDevices()
{
	printf("NOTE: MIDI not supported on your platform.\n");
	return 0;
}

#endif

int main()
{
	Option::init();

	if (chooseAudioDevices() != 0)
		return -1;
	if (chooseMIDIDevices() != 0)
		return -1;

	if (Option::writeConfigFile(Option::rcName()) != 0)
		return -1;
	printf("Configuration file \"%s\" successfully written.\n",
	                                                Option::rcName());
	return 0;
}

<|endoftext|>


<commit_before>#include <cerrno>

#include <cstdarg>

#include <cstdio>

#include <cstring>

#include <ctime>

#include <stdexcept>

#if defined(_MSC_VER)
# include <malloc.h>
#endif // _MSC_VER

namespace generic
{

//////////////////////////////////////////////////////////////////////////////
struct cformat_error : ::std::runtime_error
{
  cformat_error() : ::std::runtime_error(
    ::std::string("formatting error: ") + ::std::strerror(errno))
  {
  }
};

typedef cformat_error wcformat_error;

//////////////////////////////////////////////////////////////////////////////
inline ::std::string cformat(char const* const format, ...)
{
  va_list ap;

  int len;

  {
    va_start(ap, format);

    char tmp[64];
    len = ::std::vsnprintf(tmp, sizeof(tmp), format, ap);

    va_end(ap);

    if (len < 0)
    {
      throw cformat_error();
    }
    else if (len <= decltype(len)(sizeof(tmp)))
    {
      return {tmp, ::std::string::size_type(len)};
    }
  }

  va_start(ap, format);

#if defined(_MSC_VER)
  auto const s(static_cast<char*>(_alloca(len)));
#else
  char s[len];
#endif // _MSC_VER

  ::std::vsnprintf(s, len, format, ap);

  va_end(ap);

  return {s, ::std::string::size_type(len)};
}

//////////////////////////////////////////////////////////////////////////////
template <typename S>
inline typename ::std::enable_if<!::std::is_const<S>{}>::type
cformat(S& r, char const* const format, ...)
{
  va_list ap;

  int len;

  {
    va_start(ap, format);

    char tmp[64];
    len = ::std::vsnprintf(tmp, sizeof(tmp), format, ap);

    va_end(ap);

    if (len < 0)
    {
      throw cformat_error();
    }
    else if (len <= decltype(len)(sizeof(tmp)))
    {
      r.assign(tmp, len);

      return;
    }
  }

  va_start(ap, format);

#if defined(_MSC_VER)
  auto const s(static_cast<char*>(_alloca(len)));
#else
  char s[len];
#endif // _MSC_VER

  ::std::vsnprintf(s, len, format, ap);

  va_end(ap);

  r.assign(s, len);
}

//////////////////////////////////////////////////////////////////////////////
template <::std::size_t buffer_size = 128>
inline ::std::wstring wcformat(wchar_t const* const format, ...)
{
  static_assert(buffer_size > 0, "buffer_size must be greater than 0");

  wchar_t s[buffer_size];

  va_list ap;

  va_start(ap, format);

  if (::std::vswprintf(s, buffer_size, format, ap) >= 0)
  {
    va_end(ap);

    return s;
  }
  else
  {
    va_end(ap);

    throw wcformat_error();
  }
}

//////////////////////////////////////////////////////////////////////////////
struct strftime_array_undefined : ::std::runtime_error
{
  strftime_array_undefined() :
    ::std::runtime_error("::std::strftime() or ::std::wcsftime() returned zero")
  {
  }
};

typedef strftime_array_undefined wcsftime_array_undefined;

//////////////////////////////////////////////////////////////////////////////
template <::std::size_t buffer_size = 128>
inline ::std::string cstrftime(char const* const format,
  struct ::std::tm const* time)
{
  static_assert(buffer_size > 0, "buffer_size must be greater than 0");

#if defined(_MSC_VER)
  auto const s(static_cast<char*>(_alloca(buffer_size)));
#else
  char s[buffer_size];
#endif // _MSC_VER

  if (!::std::strftime(s, buffer_size, format, time))
  {
    throw strftime_array_undefined();
  }
  // else do nothing

  return s;
}

//////////////////////////////////////////////////////////////////////////////
template <::std::size_t buffer_size = 128>
inline ::std::wstring wcstrftime(wchar_t const* const format,
  struct ::std::tm const* time)
{
  static_assert(buffer_size > 0, "buffer_size must be greater than 0");

#if defined(_MSC_VER)
  auto const s(static_cast<char*>(_alloca(buffer_size)));
#else
  wchar_t s[buffer_size];
#endif // _MSC_VER

  if (!::std::wcsftime(s, buffer_size, format, time))
  {
    throw wcsftime_array_undefined();
  }
  // else do nothing

  return s;
}

}
<commit_msg>some fixes<commit_after>#include <cerrno>

#include <cstdarg>

#include <cstdio>

#include <cstring>

#include <ctime>

#include <stdexcept>

#if defined(_MSC_VER)
# include <malloc.h>
#endif // _MSC_VER

namespace generic
{

//////////////////////////////////////////////////////////////////////////////
struct cformat_error : ::std::runtime_error
{
  cformat_error() : ::std::runtime_error(
    ::std::string("formatting error: ") + ::std::strerror(errno))
  {
  }
};

typedef cformat_error wcformat_error;

//////////////////////////////////////////////////////////////////////////////
inline ::std::string cformat(char const* const format, ...)
{
  va_list ap;

  int len;

  {
    va_start(ap, format);

    char tmp[64];
    len = ::std::vsnprintf(tmp, sizeof(tmp), format, ap);

    va_end(ap);

    if (len < 0)
    {
      throw cformat_error();
    }
    else if (len <= decltype(len)(sizeof(tmp)))
    {
      return {tmp, ::std::string::size_type(len)};
    }
    // else do nothing
  }

  va_start(ap, format);

#if defined(_MSC_VER)
  auto const s(static_cast<char*>(_alloca(len)));
#else
  char s[len];
#endif // _MSC_VER

  ::std::vsnprintf(s, len, format, ap);

  va_end(ap);

  return {s, ::std::string::size_type(len)};
}

//////////////////////////////////////////////////////////////////////////////
template <typename S>
inline typename ::std::enable_if<!::std::is_const<S>{}>::type
cformat(S& r, char const* const format, ...)
{
  va_list ap;

  int len;

  {
    va_start(ap, format);

    char tmp[64];
    len = ::std::vsnprintf(tmp, sizeof(tmp), format, ap);

    va_end(ap);

    if (len < 0)
    {
      throw cformat_error();
    }
    else if (len <= decltype(len)(sizeof(tmp)))
    {
      r.assign(tmp, len);

      return;
    }
    // else do nothing
  }

  va_start(ap, format);

#if defined(_MSC_VER)
  auto const s(static_cast<char*>(_alloca(len)));
#else
  char s[len];
#endif // _MSC_VER

  ::std::vsnprintf(s, len, format, ap);

  va_end(ap);

  r.assign(s, len);
}

//////////////////////////////////////////////////////////////////////////////
template <::std::size_t buffer_size = 128>
inline ::std::wstring wcformat(wchar_t const* const format, ...)
{
  static_assert(buffer_size > 0, "buffer_size must be greater than 0");

  wchar_t s[buffer_size];

  va_list ap;

  va_start(ap, format);

  if (::std::vswprintf(s, buffer_size, format, ap) >= 0)
  {
    va_end(ap);

    return s;
  }
  else
  {
    va_end(ap);

    throw wcformat_error();
  }
}

//////////////////////////////////////////////////////////////////////////////
struct strftime_array_undefined : ::std::runtime_error
{
  strftime_array_undefined() :
    ::std::runtime_error("::std::strftime() or ::std::wcsftime() returned zero")
  {
  }
};

typedef strftime_array_undefined wcsftime_array_undefined;

//////////////////////////////////////////////////////////////////////////////
template <::std::size_t buffer_size = 128>
inline ::std::string cstrftime(char const* const format,
  struct ::std::tm const* time)
{
  static_assert(buffer_size > 0, "buffer_size must be greater than 0");

#if defined(_MSC_VER)
  auto const s(static_cast<char*>(_alloca(buffer_size)));
#else
  char s[buffer_size];
#endif // _MSC_VER

  if (!::std::strftime(s, buffer_size, format, time))
  {
    throw strftime_array_undefined();
  }
  // else do nothing

  return s;
}

//////////////////////////////////////////////////////////////////////////////
template <::std::size_t buffer_size = 128>
inline ::std::wstring wcstrftime(wchar_t const* const format,
  struct ::std::tm const* time)
{
  static_assert(buffer_size > 0, "buffer_size must be greater than 0");

#if defined(_MSC_VER)
  auto const s(static_cast<char*>(_alloca(buffer_size)));
#else
  wchar_t s[buffer_size];
#endif // _MSC_VER

  if (!::std::wcsftime(s, buffer_size, format, time))
  {
    throw wcsftime_array_undefined();
  }
  // else do nothing

  return s;
}

}
<|endoftext|>