mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-15 18:06:06 +01:00
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@10797 d708f5d6-7413-0410-9779-e7cbd77b26cf
135 lines
3.8 KiB
C++
135 lines
3.8 KiB
C++
/*
|
|
Copyright (C) 2011 Paul Davis
|
|
|
|
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.
|
|
|
|
This program 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 General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <cstdio> /* for ::rename() */
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
|
|
#include "pbd/file_subst.h"
|
|
#include "pbd/error.h"
|
|
#include "pbd/replace_all.h"
|
|
#include "pbd/compose.h"
|
|
|
|
#include "i18n.h"
|
|
|
|
using namespace PBD;
|
|
using namespace std;
|
|
|
|
/* this implementation assumes that the contents of the file are small enough to fit reasonably into
|
|
memory.
|
|
*/
|
|
|
|
int
|
|
PBD::file_subst (const string& path, const map<string,string>& dict)
|
|
{
|
|
ifstream in (path.c_str());
|
|
int replacements = 0;
|
|
|
|
if (!in) {
|
|
return -1;
|
|
}
|
|
|
|
/* Get the size of the file */
|
|
in.seekg(0,std::ios::end);
|
|
std::streampos length = in.tellg();
|
|
in.seekg(0,std::ios::beg);
|
|
|
|
/* allocate a string to hold the data */
|
|
|
|
string str;
|
|
|
|
try {
|
|
str.reserve (length);
|
|
} catch (exception& e) {
|
|
error << string_compose (_("could not reserve space to read substitution data from %1 (err: %2"),
|
|
path, e.what()) << endmsg;
|
|
in.close ();
|
|
return -1;
|
|
}
|
|
|
|
/* read the file contents into the string */
|
|
|
|
while (true) {
|
|
|
|
str += in.get();
|
|
|
|
if (in.eof()) {
|
|
break;
|
|
}
|
|
|
|
if (in.fail()) {
|
|
error << string_compose (_("could not read data for substitution from %1 (err: %2)"),
|
|
path, strerror (errno)) << endmsg;
|
|
in.close ();
|
|
return -1;
|
|
}
|
|
|
|
}
|
|
|
|
in.close ();
|
|
|
|
/* do the replacement */
|
|
|
|
for (map<string,string>::const_iterator i = dict.begin(); i != dict.end(); ++i) {
|
|
replacements += replace_all (str, i->first, i->second);
|
|
}
|
|
|
|
if (replacements) {
|
|
char suffix[64];
|
|
snprintf (suffix, sizeof (suffix), ".fs_%d", getpid());
|
|
string s = path + suffix;
|
|
|
|
ofstream out (s.c_str());
|
|
|
|
if (out) {
|
|
|
|
out << str;
|
|
|
|
if (!out) {
|
|
/* ignore error since we're failing anyway, although
|
|
it will leave the file around.
|
|
*/
|
|
out.close ();
|
|
(void) ::unlink (s.c_str());
|
|
return -1;
|
|
} else {
|
|
if (::rename (s.c_str(), path.c_str())) {
|
|
error << string_compose (_("Could not rename substituted file %1 to %2 (err: %3)"),
|
|
s, path, strerror (errno)) << endmsg;
|
|
(void) ::unlink (s.c_str());
|
|
out.close ();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
out.close ();
|
|
|
|
} else {
|
|
return -1;
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|