Blame synfig-core/src/synfig/main.cpp

Carlos Lopez a09598
/* === S Y N F I G ========================================================= */
Carlos Lopez a09598
/*!	\file synfig/main.cpp
Carlos Lopez a09598
**	\brief \writeme
Carlos Lopez a09598
**
Carlos Lopez a09598
**	$Id$
Carlos Lopez a09598
**
Carlos Lopez a09598
**	\legal
Carlos Lopez a09598
**	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
Carlos Lopez a09598
**	Copyright (c) 2007, 2008 Chris Moore
106d97
**	Copyright (c) 2013 Konstantin Dmitriev
Carlos Lopez a09598
**
Carlos Lopez a09598
**	This package is free software; you can redistribute it and/or
Carlos Lopez a09598
**	modify it under the terms of the GNU General Public License as
Carlos Lopez a09598
**	published by the Free Software Foundation; either version 2 of
Carlos Lopez a09598
**	the License, or (at your option) any later version.
Carlos Lopez a09598
**
Carlos Lopez a09598
**	This package is distributed in the hope that it will be useful,
Carlos Lopez a09598
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
Carlos Lopez a09598
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Carlos Lopez a09598
**	General Public License for more details.
Carlos Lopez a09598
**	\endlegal
Carlos Lopez a09598
*/
Carlos Lopez a09598
/* ========================================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === H E A D E R S ======================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
#ifdef USING_PCH
Carlos Lopez a09598
#	include "pch.h"
Carlos Lopez a09598
#else
Carlos Lopez a09598
#ifdef HAVE_CONFIG_H
Carlos Lopez a09598
#	include <config.h></config.h>
Carlos Lopez a09598
#endif
Carlos Lopez a09598
bw 94d8a6
#include <synfig localization.h=""></synfig>
bw 94d8a6
#include <synfig general.h=""></synfig>
bw 94d8a6
Carlos Lopez a09598
#include <iostream></iostream>
Carlos Lopez a09598
#include "version.h"
Carlos Lopez a09598
#include "general.h"
Carlos Lopez a09598
#include "module.h"
Carlos Lopez a09598
#include <cstdlib></cstdlib>
Carlos Lopez a09598
#include <ltdl.h></ltdl.h>
873d31
#include <glibmm.h></glibmm.h>
Carlos Lopez a09598
#include <stdexcept></stdexcept>
d0e399
57e14b
// Includes used by get_binary_path():
10a93e
#ifdef _WIN32
1855b6
#include <windows.h></windows.h>
d0e399
#elif defined(__APPLE__)
cae9c6
#include <mach-o dyld.h=""></mach-o>
6d5035
#include <sys param.h=""></sys>
1855b6
#else
360d76
#include <sys stat.h=""></sys>
1855b6
#include <unistd.h></unistd.h>
1855b6
#endif
d0e399
48c23f
#include "token.h"
Carlos Lopez a09598
#include "target.h"
Carlos Lopez a09598
#include <etl stringf=""></etl>
Carlos Lopez 0d0b95
#include "cairolistimporter.h"
Carlos Lopez a09598
#include "listimporter.h"
Carlos Lopez b9c525
#include "cairoimporter.h"
Carlos Lopez a09598
#include "color.h"
Carlos Lopez a09598
#include "vector.h"
Carlos Lopez a09598
#include <fstream></fstream>
f14a1d
#include <time.h></time.h>
Carlos Lopez a09598
#include "layer.h"
Carlos Lopez a09598
#include "valuenode.h"
979b7d
#include "soundprocessor.h"
162b7b
#include "rendering/renderer.h"
Carlos Lopez a09598
Carlos Lopez a09598
#include "main.h"
Carlos Lopez a09598
#include "loadcanvas.h"
Carlos Lopez a09598
Carlos Lopez a09598
#include "guid.h"
Carlos Lopez a09598
187f64
#include <giomm.h></giomm.h>
187f64
Carlos Lopez a09598
#ifdef HAVE_SIGNAL_H
Carlos Lopez a09598
#include <signal.h></signal.h>
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Dmitry Smirnov 20a94b
#ifndef PATH_MAX
Dmitry Smirnov 20a94b
#define PATH_MAX 4096
Dmitry Smirnov 20a94b
#endif
Dmitry Smirnov 20a94b
Carlos Lopez a09598
using namespace etl;
Carlos Lopez a09598
using namespace synfig;
Carlos Lopez a09598
Carlos Lopez a09598
/* === M A C R O S ========================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
#define MODULE_LIST_FILENAME	"synfig_modules.cfg"
Carlos Lopez a09598
Carlos Lopez a09598
/* === S T A T I C S ======================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
static etl::reference_counter synfig_ref_count_(0);
74142e
Main *Main::instance = NULL;
b297b1
b297b1
class GeneralIOMutexHolder {
b297b1
private:
Rodolfo Ribeiro Gomes cfe072
	std::mutex mutex;
b297b1
	bool initialized;
b297b1
public:
b297b1
	GeneralIOMutexHolder(): initialized(true) { }
b297b1
	~GeneralIOMutexHolder() { initialized = false; }
Rodolfo Ribeiro Gomes cfe072
	void lock() { if (initialized) mutex.lock(); }
Rodolfo Ribeiro Gomes cfe072
	void unlock() { if (initialized) mutex.unlock(); }
b297b1
};
b297b1
b297b1
GeneralIOMutexHolder general_io_mutex;
Carlos Lopez a09598
Carlos Lopez a09598
/* === P R O C E D U R E S ================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === M E T H O D S ======================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
const char *
Carlos Lopez a09598
synfig::get_version()
Carlos Lopez a09598
{
Carlos Lopez a09598
#ifdef VERSION
Carlos Lopez a09598
	return VERSION;
Carlos Lopez a09598
#else
Carlos Lopez a09598
	return "Unknown";
Carlos Lopez a09598
#endif
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
const char *
Carlos Lopez a09598
synfig::get_build_date()
Carlos Lopez a09598
{
Carlos Lopez a09598
	return __DATE__;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
bool
bb947e
synfig::check_version_(size_t version, size_t vec_size, size_t color_size, size_t canvas_size, size_t layer_size)
Carlos Lopez a09598
{
Carlos Lopez a09598
	bool ret=true;
Carlos Lopez a09598
Carlos Lopez a09598
	if(version!=SYNFIG_LIBRARY_VERSION)
Carlos Lopez a09598
	{
bb947e
		synfig::error(_("API Version mismatch (LIB:%zu, PROG:%zu)"), SYNFIG_LIBRARY_VERSION, version);
Carlos Lopez a09598
		ret=false;
Carlos Lopez a09598
	}
Carlos Lopez a09598
	if(vec_size!=sizeof(Vector))
Carlos Lopez a09598
	{
bb947e
		synfig::error(_("Size of Vector mismatch (app:%zu, lib:%zu)"),vec_size,sizeof(Vector));
Carlos Lopez a09598
		ret=false;
Carlos Lopez a09598
	}
Carlos Lopez a09598
	if(color_size!=sizeof(Color))
Carlos Lopez a09598
	{
bb947e
		synfig::error(_("Size of Color mismatch (app:%zu, lib:%zu)"),color_size,sizeof(Color));
Carlos Lopez a09598
		ret=false;
Carlos Lopez a09598
	}
Carlos Lopez a09598
	if(canvas_size!=sizeof(Canvas))
Carlos Lopez a09598
	{
bb947e
		synfig::error(_("Size of Canvas mismatch (app:%zu, lib:%zu)"),canvas_size,sizeof(Canvas));
Carlos Lopez a09598
		ret=false;
Carlos Lopez a09598
	}
Carlos Lopez a09598
	if(layer_size!=sizeof(Layer))
Carlos Lopez a09598
	{
bb947e
		synfig::error(_("Size of Layer mismatch (app:%zu, lib:%zu)"),layer_size,sizeof(Layer));
Carlos Lopez a09598
		ret=false;
Carlos Lopez a09598
	}
Carlos Lopez a09598
Carlos Lopez a09598
	return ret;
Carlos Lopez a09598
}
Carlos Lopez a09598
ec1247
static void broken_pipe_signal (int /*sig*/)  {
Carlos Lopez a09598
	synfig::warning("Broken Pipe...");
ec1247
}
Carlos Lopez a09598
Carlos Lopez a09598
bool retrieve_modules_to_load(String filename,std::list<string> &modules_to_load)</string>
Carlos Lopez a09598
{
c55bbc
	std::ifstream file(Glib::locale_from_utf8(filename).c_str());
Carlos Lopez a09598
Carlos Lopez a09598
	if(!file)
Carlos Lopez a09598
	{
c55bbc
		synfig::warning("Cannot open "+filename);
Carlos Lopez a09598
		return false;
Carlos Lopez a09598
	}
Carlos Lopez a09598
Carlos Lopez a09598
	while(file)
Carlos Lopez a09598
	{
Carlos Lopez a09598
		String modulename;
Carlos Lopez a09598
		getline(file,modulename);
Carlos Lopez a09598
		if(!modulename.empty() && find(modules_to_load.begin(),modules_to_load.end(),modulename)==modules_to_load.end())
Carlos Lopez a09598
			modules_to_load.push_back(modulename);
Carlos Lopez a09598
	}
Carlos Lopez a09598
Carlos Lopez a09598
	return true;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
synfig::Main::Main(const synfig::String& basepath,ProgressCallback *cb):
Carlos Lopez a09598
	ref_count_(synfig_ref_count_)
Carlos Lopez a09598
{
Carlos Lopez a09598
	if(ref_count_.count())
Carlos Lopez a09598
		return;
Carlos Lopez a09598
Carlos Lopez a09598
	synfig_ref_count_.reset();
Carlos Lopez a09598
	ref_count_=synfig_ref_count_;
Carlos Lopez a09598
74142e
	assert(!instance);
74142e
	instance = this;
74142e
74142e
	// Paths
74142e
74142e
	root_path       = etl::dirname(basepath);
74142e
	bin_path        = root_path  + ETL_DIRECTORY_SEPARATOR + "bin";
74142e
	share_path      = root_path  + ETL_DIRECTORY_SEPARATOR + "share";
74142e
	locale_path     = share_path + ETL_DIRECTORY_SEPARATOR + "locale";
74142e
	lib_path        = root_path  + ETL_DIRECTORY_SEPARATOR + "lib";
74142e
	lib_synfig_path = lib_path   + ETL_DIRECTORY_SEPARATOR + "synfig";
74142e
Carlos Lopez a09598
	// Add initialization after this point
Carlos Lopez a09598
Carlos Lopez a09598
#ifdef ENABLE_NLS
873d31
	String locale_dir;
74142e
	locale_dir = locale_path;
1855b6
c55bbc
	bindtextdomain("synfig", Glib::locale_from_utf8(locale_path).c_str() );
Carlos Lopez a09598
	bind_textdomain_codeset("synfig", "UTF-8");
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
	unsigned int i;
Carlos Lopez a09598
#ifdef _DEBUG
Carlos Lopez 97a475
#ifndef __APPLE__
Carlos Lopez a09598
	std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
Carlos Lopez a09598
#endif
Carlos Lopez 97a475
#endif
Carlos Lopez a09598
Carlos Lopez a09598
#if defined(HAVE_SIGNAL_H) && defined(SIGPIPE)
Carlos Lopez a09598
	signal(SIGPIPE, broken_pipe_signal);
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
	//_config_search_path=new vector"string.h"();
187f64
	
187f64
	// Init Gio to allow use Gio::File::create_for_uri() in ValueNode_AnimatedFile::load file() function
187f64
	Gio::init();
Carlos Lopez a09598
Carlos Lopez a09598
	// Init the subsystems
Carlos Lopez a09598
	if(cb)cb->amount_complete(0, 100);
d89783
979b7d
	if(cb)cb->task(_("Starting Subsystem \"Sound\""));
979b7d
	if(!SoundProcessor::subsys_init())
979b7d
		throw std::runtime_error(_("Unable to initialize subsystem \"Sound\""));
979b7d
d89783
	if(cb)cb->task(_("Starting Subsystem \"Types\""));
d89783
	if(!Type::subsys_init())
162b7b
	{
162b7b
		SoundProcessor::subsys_stop();
d89783
		throw std::runtime_error(_("Unable to initialize subsystem \"Types\""));
162b7b
	}
162b7b
162b7b
	if(cb)cb->task(_("Starting Subsystem \"Rendering\""));
162b7b
	if(!rendering::Renderer::subsys_init())
162b7b
	{
162b7b
		Type::subsys_stop();
162b7b
		SoundProcessor::subsys_stop();
162b7b
		throw std::runtime_error(_("Unable to initialize subsystem \"Rendering\""));
162b7b
	}
d89783
Carlos Lopez a09598
	if(cb)cb->task(_("Starting Subsystem \"Modules\""));
74142e
	if(!Module::subsys_init(root_path))
79bd59
	{
162b7b
		rendering::Renderer::subsys_stop();
79bd59
		Type::subsys_stop();
162b7b
		SoundProcessor::subsys_stop();
d89783
		throw std::runtime_error(_("Unable to initialize subsystem \"Modules\""));
79bd59
	}
Carlos Lopez a09598
Carlos Lopez a09598
	if(cb)cb->task(_("Starting Subsystem \"Layers\""));
Carlos Lopez a09598
	if(!Layer::subsys_init())
Carlos Lopez a09598
	{
Carlos Lopez a09598
		Module::subsys_stop();
162b7b
		rendering::Renderer::subsys_stop();
79bd59
		Type::subsys_stop();
162b7b
		SoundProcessor::subsys_stop();
Carlos Lopez a09598
		throw std::runtime_error(_("Unable to initialize subsystem \"Layers\""));
Carlos Lopez a09598
	}
Carlos Lopez a09598
Carlos Lopez a09598
	if(cb)cb->task(_("Starting Subsystem \"Targets\""));
Carlos Lopez a09598
	if(!Target::subsys_init())
Carlos Lopez a09598
	{
Carlos Lopez a09598
		Layer::subsys_stop();
Carlos Lopez a09598
		Module::subsys_stop();
162b7b
		rendering::Renderer::subsys_stop();
79bd59
		Type::subsys_stop();
162b7b
		SoundProcessor::subsys_stop();
Carlos Lopez a09598
		throw std::runtime_error(_("Unable to initialize subsystem \"Targets\""));
Carlos Lopez a09598
	}
Carlos Lopez a09598
Carlos Lopez a09598
	if(cb)cb->task(_("Starting Subsystem \"Importers\""));
Carlos Lopez a09598
	if(!Importer::subsys_init())
Carlos Lopez a09598
	{
Carlos Lopez a09598
		Target::subsys_stop();
Carlos Lopez a09598
		Layer::subsys_stop();
Carlos Lopez a09598
		Module::subsys_stop();
162b7b
		rendering::Renderer::subsys_stop();
79bd59
		Type::subsys_stop();
162b7b
		SoundProcessor::subsys_stop();
Carlos Lopez a09598
		throw std::runtime_error(_("Unable to initialize subsystem \"Importers\""));
Carlos Lopez a09598
	}
Carlos Lopez a09598
Carlos Lopez b9c525
	if(cb)cb->task(_("Starting Subsystem \"Cairo Importers\""));
Carlos Lopez b9c525
	if(!CairoImporter::subsys_init())
Carlos Lopez b9c525
	{
Carlos Lopez b9c525
		Importer::subsys_stop();
Carlos Lopez b9c525
		Target::subsys_stop();
Carlos Lopez b9c525
		Layer::subsys_stop();
Carlos Lopez b9c525
		Module::subsys_stop();
162b7b
		rendering::Renderer::subsys_stop();
79bd59
		Type::subsys_stop();
162b7b
		SoundProcessor::subsys_stop();
Carlos Lopez b9c525
		throw std::runtime_error(_("Unable to initialize subsystem \"Cairo Importers\""));
Carlos Lopez b9c525
	}
Carlos Lopez b9c525
48c23f
	// Rebuild tokens data
48c23f
	Token::rebuild();
48c23f
Carlos Lopez a09598
	// Load up the list importer
38a4d5
	Importer::book()[String("lst")]=Importer::BookEntry(ListImporter::create, ListImporter::supports_file_system_wrapper__);
38a4d5
	CairoImporter::book()[String("lst")]=CairoImporter::BookEntry(CairoListImporter::create, CairoListImporter::supports_file_system_wrapper__);
Carlos Lopez a09598
Carlos Lopez a09598
	// Load up the modules
Carlos Lopez a09598
	std::list<string> modules_to_load;</string>
Carlos Lopez a09598
	std::vector<string> locations;</string>
Carlos Lopez a09598
Carlos Lopez a09598
	if(getenv("SYNFIG_MODULE_LIST"))
Carlos Lopez a09598
		locations.push_back(getenv("SYNFIG_MODULE_LIST"));
Carlos Lopez a09598
	else
Carlos Lopez a09598
	{
9aaa53
		locations.push_back("./" MODULE_LIST_FILENAME);
Carlos Lopez a09598
		if(getenv("HOME"))
7b25de
			locations.push_back(strprintf("%s/.local/share/synfig/%s", getenv("HOME"), MODULE_LIST_FILENAME));
Carlos Lopez a09598
	#ifdef SYSCONFDIR
9aaa53
		locations.push_back(SYSCONFDIR"/" MODULE_LIST_FILENAME);
Carlos Lopez a09598
	#endif
74142e
		locations.push_back(root_path + ETL_DIRECTORY_SEPARATOR + "etc" + ETL_DIRECTORY_SEPARATOR + MODULE_LIST_FILENAME);
9aaa53
		locations.push_back("/usr/local/etc/" MODULE_LIST_FILENAME);
Carlos Lopez a09598
	#ifdef __APPLE__
9aaa53
		locations.push_back("/Library/Frameworks/synfig.framework/Resources/" MODULE_LIST_FILENAME);
9aaa53
		locations.push_back("/Library/Synfig/" MODULE_LIST_FILENAME);
Carlos Lopez a09598
		if(getenv("HOME"))
Carlos Lopez a09598
			locations.push_back(strprintf("%s/Library/Synfig/%s", getenv("HOME"), MODULE_LIST_FILENAME));
Carlos Lopez a09598
	#endif
Carlos Lopez a09598
	}
Carlos Lopez a09598
Carlos Lopez a09598
	for(i=0;i
Carlos Lopez a09598
		if(retrieve_modules_to_load(locations[i],modules_to_load))
Carlos Lopez a09598
		{
c55bbc
			synfig::info(_("Loading modules from %s"), Glib::locale_from_utf8(locations[i]).c_str());
Carlos Lopez a09598
			if(cb)cb->task(strprintf(_("Loading modules from %s"),locations[i].c_str()));
Carlos Lopez a09598
			break;
Carlos Lopez a09598
		}
Carlos Lopez a09598
Carlos Lopez a09598
	if (i == locations.size())
caryoscelus e54a41
	{
caryoscelus e54a41
		synfig::warning("Cannot find '%s', trying to load default modules", MODULE_LIST_FILENAME);
caryoscelus e54a41
		Module::register_default_modules(cb);
caryoscelus e54a41
	}
Carlos Lopez a09598
Carlos Lopez a09598
	std::list<string>::iterator iter;</string>
Carlos Lopez a09598
Carlos Lopez a09598
	for(i=0,iter=modules_to_load.begin();iter!=modules_to_load.end();++iter,i++)
Carlos Lopez a09598
	{
caryoscelus d992eb
		synfig::info("Loading %s..", iter->c_str());
Carlos Lopez a09598
		Module::Register(*iter,cb);
Carlos Lopez a09598
		if(cb)cb->amount_complete((i+1)*100,modules_to_load.size()*100);
Carlos Lopez a09598
	}
Carlos Lopez a09598
e03d25
	// Rebuild tokens data again to include new tokens from modules
e03d25
	Token::rebuild();
e03d25
Carlos Lopez a09598
	if(cb)cb->amount_complete(100, 100);
Carlos Lopez a09598
	if(cb)cb->task(_("DONE"));
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
synfig::Main::~Main()
Carlos Lopez a09598
{
Carlos Lopez a09598
	ref_count_.detach();
Carlos Lopez a09598
	if(!synfig_ref_count_.unique())
Carlos Lopez a09598
		return;
Carlos Lopez a09598
	synfig_ref_count_.detach();
Carlos Lopez a09598
Carlos Lopez a09598
	// Add deinitialization after this point
Carlos Lopez a09598
Carlos Lopez a09598
	if(get_open_canvas_map().size())
Carlos Lopez a09598
	{
Carlos Lopez a09598
		synfig::warning("Canvases still open!");
Carlos Lopez a09598
		std::map<synfig::string, etl::loose_handle<canvas=""> >::iterator iter;</synfig::string,>
Carlos Lopez a09598
		for(iter=get_open_canvas_map().begin();iter!=get_open_canvas_map().end();++iter)
Carlos Lopez a09598
		{
Carlos Lopez a09598
			synfig::warning("%s: count()=%d",iter->first.c_str(), iter->second.count());
Carlos Lopez a09598
		}
Carlos Lopez a09598
	}
Carlos Lopez a09598
Carlos Lopez a09598
	// synfig::info("Importer::subsys_stop()");
Carlos Lopez a09598
	Importer::subsys_stop();
Carlos Lopez b9c525
	CairoImporter::subsys_stop();
Carlos Lopez a09598
	// synfig::info("Target::subsys_stop()");
Carlos Lopez a09598
	Target::subsys_stop();
Carlos Lopez a09598
	// synfig::info("Layer::subsys_stop()");
Carlos Lopez a09598
	Layer::subsys_stop();
Carlos Lopez a09598
	/*! \todo For some reason, uncommenting the next line will cause things to crash.
Carlos Lopez a09598
			  This needs to be looked into at some point. */
Carlos Lopez a09598
 	// synfig::info("Module::subsys_stop()");
Carlos Lopez a09598
	// Module::subsys_stop();
Carlos Lopez a09598
	// synfig::info("Exiting");
162b7b
	rendering::Renderer::subsys_stop();
79bd59
	Type::subsys_stop();
162b7b
	SoundProcessor::subsys_stop();
Carlos Lopez a09598
Carlos Lopez a09598
#if defined(HAVE_SIGNAL_H) && defined(SIGPIPE)
Carlos Lopez a09598
	signal(SIGPIPE, SIG_DFL);
Carlos Lopez a09598
#endif
74142e
74142e
	assert(instance);
74142e
	instance = NULL;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
static const String
Carlos Lopez a09598
current_time()
Carlos Lopez a09598
{
Carlos Lopez a09598
	const int buflen = 50;
Carlos Lopez a09598
	time_t t;
Carlos Lopez a09598
	struct tm *lt;
Carlos Lopez a09598
	char b[buflen];
Carlos Lopez a09598
	time(&t);
Carlos Lopez a09598
	lt = localtime(&t);
Carlos Lopez a09598
	strftime(b, buflen, " [%X] ", lt);
Carlos Lopez a09598
	return String(b);
Carlos Lopez a09598
}
Carlos Lopez a09598
9dfcef
bool synfig::synfig_quiet_mode = false;
9dfcef
Carlos Lopez a09598
void
Carlos Lopez a09598
synfig::error(const char *format,...)
Carlos Lopez a09598
{
Carlos Lopez a09598
	va_list args;
3e2a84
	va_start(args, format);
3e2a84
	error(vstrprintf(format, args));
3e2a84
	va_end(args);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
Carlos Lopez a09598
synfig::error(const String &str)
Carlos Lopez a09598
{
b297b1
	general_io_mutex.lock();
Rodolfo Ribeiro Gomes cfe072
	std::cerr<<"\033[31m"<<"synfig("<
b297b1
	general_io_mutex.unlock();
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
Carlos Lopez a09598
synfig::warning(const char *format,...)
Carlos Lopez a09598
{
Carlos Lopez a09598
	va_list args;
Carlos Lopez a09598
	va_start(args,format);
Carlos Lopez a09598
	warning(vstrprintf(format,args));
3e2a84
	va_end(args);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
Carlos Lopez a09598
synfig::warning(const String &str)
Carlos Lopez a09598
{
b297b1
	general_io_mutex.lock();
Rodolfo Ribeiro Gomes cfe072
	std::cerr<<"\033[33m"<<"synfig("<
b297b1
	general_io_mutex.unlock();
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
Carlos Lopez a09598
synfig::info(const char *format,...)
Carlos Lopez a09598
{
Carlos Lopez a09598
	va_list args;
3e2a84
	va_start(args, format);
3e2a84
	info(vstrprintf(format, args));
3e2a84
	va_end(args);
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
Carlos Lopez a09598
synfig::info(const String &str)
Carlos Lopez a09598
{
9dfcef
	//if (SynfigToolGeneralOptions::instance()->should_be_quiet()) return; // don't show info messages in quiet mode
9dfcef
	if (synfig::synfig_quiet_mode) return;
9dfcef
b297b1
	general_io_mutex.lock();
Rodolfo Ribeiro Gomes cfe072
	std::cout<<"synfig("<
b297b1
	general_io_mutex.unlock();
Carlos Lopez a09598
}
360d76
57e14b
// synfig::get_binary_path()
57e14b
// See also: http://libsylph.sourceforge.net/wiki/Full_path_to_binary
57e14b
360d76
String
b2aa8a
synfig::get_binary_path(const String &fallback_path)
360d76
{
448557
	
569935
	String result;
1855b6
10a93e
#ifdef _WIN32
448557
	
448557
	size_t buf_size = PATH_MAX - 1;
448557
	char* path = (char*)malloc(buf_size);
448557
	
1855b6
	GetModuleFileName(NULL, path, PATH_MAX);
1855b6
569935
	result = String(path);
448557
	
448557
	free(path);
1855b6
569935
#elif defined(__APPLE__)
569935
	
448557
	uint32_t buf_size = MAXPATHLEN;
448557
	char* path = (char*)malloc(MAXPATHLEN);
cae9c6
	
448557
	if(_NSGetExecutablePath(path, &buf_size) == -1 ) {
448557
		path = (char*)realloc(path, buf_size);
448557
		_NSGetExecutablePath(path, &buf_size);
cae9c6
	}
cae9c6
	
448557
	result = String(path);
448557
	
448557
	free(path);
cae9c6
	
cae9c6
	// "./synfig" case workaround
cae9c6
	String artifact("/./");
cae9c6
	size_t start_pos = result.find(artifact);
cae9c6
	if (start_pos != std::string::npos)
cae9c6
		result.replace(start_pos, artifact.length(), "/");
569935
	
37ade5
#elif !defined(__OpenBSD__)
1855b6
448557
	size_t buf_size = PATH_MAX - 1;
448557
	char* path = (char*)malloc(buf_size);
448557
1855b6
	ssize_t size;
1855b6
	struct stat stat_buf;
1855b6
	FILE *f;
1855b6
1855b6
	/* Read from /proc/self/exe (symlink) */
3b3e3e
	//char* path2 = (char*)malloc(buf_size);
3b3e3e
	char* path2 = new char[buf_size];
1855b6
	strncpy(path2, "/proc/self/exe", buf_size - 1);
360d76
1855b6
	while (1) {
1855b6
		int i;
360d76
1855b6
		size = readlink(path2, path, buf_size - 1);
1855b6
		if (size == -1) {
1855b6
			/* Error. */
1855b6
			break;
1855b6
		}
360d76
1855b6
		/* readlink() success. */
1855b6
		path[size] = '\0';
360d76
1855b6
		/* Check whether the symlink's target is also a symlink.
1855b6
		 * We want to get the final target. */
1855b6
		i = stat(path, &stat_buf);
1855b6
		if (i == -1) {
1855b6
			/* Error. */
1855b6
			break;
1855b6
		}
360d76
1855b6
		/* stat() success. */
1855b6
		if (!S_ISLNK(stat_buf.st_mode)) {
360d76
360d76
			/* path is not a symlink. Done. */
569935
			result = String(path);
448557
			
569935
			break;
1855b6
		}
360d76
1855b6
		/* path is a symlink. Continue loop and resolve this. */
1855b6
		strncpy(path, path2, buf_size - 1);
1855b6
	}
448557
	
3b3e3e
	//free(path2);
3b3e3e
	delete[] path2;
360d76
569935
	if (result == "")
569935
	{
569935
		/* readlink() or stat() failed; this can happen when the program is
569935
		 * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
360d76
569935
		buf_size = PATH_MAX + 128;
448557
		char* line = (char*)malloc(buf_size);
360d76
569935
		f = fopen("/proc/self/maps", "r");
569935
		if (f == NULL) {
569935
			synfig::error("Cannot open /proc/self/maps.");
569935
		}
360d76
569935
		/* The first entry should be the executable name. */
569935
		char *r;
569935
		r = fgets(line, (int) buf_size, f);
569935
		if (r == NULL) {
569935
			synfig::error("Cannot read /proc/self/maps.");
569935
		}
360d76
569935
		/* Get rid of newline character. */
569935
		buf_size = strlen(line);
569935
		if (buf_size <= 0) {
569935
			/* Huh? An empty string? */
569935
			synfig::error("Invalid /proc/self/maps.");
569935
		}
569935
		if (line[buf_size - 1] == 10)
569935
			line[buf_size - 1] = 0;
1855b6
569935
		/* Extract the filename; it is always an absolute path. */
569935
		path = strchr(line, '/');
1855b6
569935
		/* Sanity check. */
569935
		if (strstr(line, " r-xp ") == NULL || path == NULL) {
569935
			synfig::error("Invalid /proc/self/maps.");
569935
		}
1855b6
569935
		result = String(path);
448557
		free(line);
569935
		fclose(f);
1855b6
	}
448557
	
448557
	free(path);
1855b6
1855b6
#endif
569935
	
b2aa8a
	if (result == "")
b2aa8a
	{
b2aa8a
		// In worst case use value specified as fallback 
b2aa8a
		// (usually should come from argv[0])
448557
		result = etl::absolute_path(fallback_path);
b2aa8a
	}
c55bbc
	
c55bbc
	result = Glib::locale_to_utf8(result);
c55bbc
	
569935
	return result;
cae9c6
}