21#include "rheolef/rheostream.h"
22#include "rheolef/iorheo.h"
28#pragma GCC diagnostic push
29#pragma GCC diagnostic ignored "-Weffc++"
30#include <boost/iostreams/filter/gzip.hpp>
31#include <boost/iostreams/device/file.hpp>
32#pragma GCC diagnostic pop
34#ifdef _RHEOLEF_HAVE_UNISTD_H
38#ifdef _RHEOLEF_HAVE_SYMLINK_H
51namespace ios = boost::iostreams;
55 char* c_tmpdir = std::getenv (
"TMPDIR");
56 return (c_tmpdir == 0) ?
"/tmp" : c_tmpdir;
61 std::ostringstream out;
69 : ios::filtering_stream<ios::output>(),
73 open (name, suffix, mode);
84 if (suffix.length() == 0) {
94 bool verbose = iorheo::getverbose(clog);
96 std::string action = (mode &
io::app) ?
"appended" :
"created";
97 clog <<
"! file \"" <<
_full_name <<
"\" " << action << endl;
106 filtering_stream<output>::push (gzip_compressor());
109 std::ios_base::openmode om = std::ios_base::out | std::ios_base::binary;
110 if (mode &
io::app) { om |= std::ios_base::app; }
112 filtering_stream<output>::push (ofs);
118 if (filtering_stream<ios::output>::empty()) {
121#define _RHEOLEF_HAVE_BOOST_IOSTREAMS_GZIP_EMPTY_FILE_BUG
122#ifdef _RHEOLEF_HAVE_BOOST_IOSTREAMS_GZIP_EMPTY_FILE_BUG
127#ifdef _RHEOLEF_HAVE_BOOST_IOSTREAMS_GZIP_EMPTY_FILE_BUG_OLD
132 trace_macro (
"_close_internal: _full_name="<<
_full_name<<
": gziped => add a carriage return before closing...");
133 static char dummy =
'\n';
134 static size_t length = 1;
135 filtering_stream<ios::output>::component<gzip_compressor>(0)->write(*filtering_stream<ios::output>::component<file_sink>(1), &dummy, length);
138 while (! filtering_stream<ios::output>::empty()) {
139 filtering_stream<ios::output>::pop();
168 if (full_name.length() == 0) {
169 if (suffix.length() != 0) {
170 error_macro (
"file \"" << name <<
"[." << suffix <<
"[.gz]]\" not found");
172 error_macro (
"file \"" << name <<
"[.gz]\" not found");
178 _ifs.open (full_name.c_str(), ios_base::in);
180 _ifs.open (full_name.c_str(), ios_base::in | ios_base::binary);
182 bool verbose = iorheo::getverbose(clog);
183 if (verbose) clog <<
"! load \"" << full_name <<
"\"\n";
187 filtering_stream<input>::push (gzip_decompressor());
189 filtering_stream<input>::push (
_ifs);
195 while (! filtering_stream<ios::input>::empty()) {
196 filtering_stream<ios::input>::pop();
201 : ios::filtering_stream<ios::input>(), _ifs()
214 size_t ln = name.length();
215 size_t ls = suffix.length();
216 if (ln <= ls+1)
return false;
218 if (name[ln-ls-1] !=
'.')
return false;
219 for (
size_t i = ln-ls, j = 0; i < ln; i++, j++)
220 if (name [i] != suffix [j])
return false;
229 return string(name, 0, name.length() - suffix.length() - 1);
235 size_t ln = name.length();
236 if (ln == 0)
return false;
237 for (
size_t i = ln-1; i > 0 && name[i] !=
'/'; --i)
238 if (name [i] ==
'.')
return true;
245 size_t ln = name.length();
246 if (ln == 0)
return name;
248 for (
size_t i = ln-1; i > 0 && name[i] !=
'/'; --i) {
249 if (name [i] ==
'.') {
254 if (i_dot == 0)
return name;
255 return string(name, 0, i_dot);
260 string::size_type l = name.length();
261 string::size_type i = name.find_last_of (
'/');
262 if (i >= l)
return name;
263 string b = string(name, i+1, l-i-1);
269 string::size_type l = name.length();
270 string::size_type i = name.find_last_of (
'/');
271 if (i >= l)
return ".";
272 string d = string(name, 0, i);
289get_dir_from_path (
const string& path,
unsigned int& i_pos)
292 unsigned int last = path.length();
297 while (i_pos < last && path [i_pos] ==
':')
305 unsigned int i_last = i_pos;
306 for (i_last = i_pos; i_last < last && path [i_last] !=
':'; i_last++);
309 current_dir = string(path, i_pos, i_last-i_pos+1);
311 current_dir = string(path, i_pos, i_last-i_pos);
326 const char *s1 = getenv (rheo_path_name);
328 s1 = default_rheo_path;
330 rheo_path = new_tab_macro(
char, strlen(s1)+1);
331 strcpy (rheo_path, s1);
337 string tmp = string(rheo_path) +
":" + dir;
338 delete_tab_macro(rheo_path);
339 rheo_path = new_tab_macro(
char, strlen(tmp.c_str())+1);
340 strcpy (rheo_path, tmp.c_str());
346 string tmp = dir +
":" + string(rheo_path);
347 delete_tab_macro(rheo_path);
348 rheo_path = new_tab_macro(
char, strlen(tmp.c_str())+1);
349 strcpy (rheo_path, tmp.c_str());
353have_name_in_dir (
const string& dir,
const string& name,
string& full_path)
368 if (unzip_status && zip_status) {
369 warning_macro (
"both compressed and uncompressed files exists:");
372 error_macro (
"unrecoverable ambiguous situation (HINT: rename one of these files)");
376 full_path = zip_full_name;
380 full_path = unzip_full_name;
385 if (stat(dir.c_str(), &sd) != 0) {
387 warning_macro (
"hint: check "<< rheo_path_name <<
" or -I options");
390 if ((sd.st_mode & S_IFDIR) == 0) {
392 warning_macro (
"hint: check "<< rheo_path_name <<
" or -I options");
396 DIR*
d = opendir(dir.c_str());
399 warning_macro (
"hint: check "<< rheo_path_name <<
" or -I options");
403 while ((dp = readdir(
d)) != 0) {
405 string subdir = dir +
"/" + (dp -> d_name);
407 if (strcmp(dp -> d_name,
".") == 0 ||
408 strcmp(dp -> d_name,
"..") == 0)
continue;
411 if (stat(subdir.c_str(), &s) != 0) {
415 if ((s.st_mode & S_IFLNK) == 0) {
419 char* subdir_cstr = (
char*)(subdir.c_str());
420 int linksize = readlink (subdir_cstr, linkname,
PATH_MAX + 1);
432 linkname [linksize] =
'\0';
433 if (strcmp(linkname,
".") == 0 ||
434 strcmp(linkname,
"..") == 0) {
439 if ((s.st_mode & S_IFDIR) != 0) {
441 if (have_name_in_dir (subdir, name, full_path)) {
451 if (rootname ==
"") {
455 if (suffix !=
"") name +=
"." + suffix;
458 if (rootname [0] ==
'.' || rootname[0] ==
'/') {
459 if (have_name_in_dir (
"", name, full_path)) {
468 unsigned int i_dir = 0;
469 string dir = get_dir_from_path (rheo_path, i_dir);
470 while (dir.length() != 0) {
472 if (have_name_in_dir (dir, name, full_path)) {
475 dir = get_dir_from_path (rheo_path, i_dir);
488 unsigned int l = s.length();
489 if (l < 1)
return false;
490 if (!isdigit(s[0]) && s[0] !=
'-' && s[0] !=
'.')
return false;
492 if (l < 2)
return false;
493 if (!isdigit(s[1]) && s[1] !=
'.')
return false;
see the Float page for the full documentation
void open(const std::string &name, const std::string &suffix=std::string())
void _open_internal(io::mode_type mode)
void open(const std::string &name, const std::string &suffix=std::string(), io::mode_type mode=io::out)
static const char * default_rheo_path
static const char * rheo_path_name
#define trace_macro(message)
#define error_macro(message)
#define warning_macro(message)
This file is part of Rheolef.
string get_dirname(const string &name)
get_dirname: see the rheostream page for the full documentation
string delete_suffix(const string &name, const string &suffix)
delete_suffix: see the rheostream page for the full documentation
void prepend_dir_to_rheo_path(const string &dir)
prepend_dir_to_rheo_path: see the rheostream page for the full documentation
Float to_float(const string &s)
to_float: see the rheostream page for the full documentation
string get_basename(const string &name)
get_basename: see the rheostream page for the full documentation
std::string get_tmpdir()
get_tmpdir: see the rheostream page for the full documentation
bool has_suffix(const string &name, const string &suffix)
has_suffix: see the rheostream page for the full documentation
void append_dir_to_rheo_path(const string &dir)
append_dir_to_rheo_path: see the rheostream page for the full documentation
string delete_any_suffix(const string &name)
delete_any_suffix: see the rheostream page for the full documentation
string get_full_name_from_rheo_path(const string &rootname, const string &suffix)
get_full_name_from_rheo_path: see the rheostream page for the full documentation
bool is_float(const string &s)
is_float: see the rheostream page for the full documentation
string ftos(const Float &x)
itof: see the rheostream page for the full documentation
bool file_exists(const std::string &filename)
file_exists: see the rheostream page for the full documentation
bool has_any_suffix(const string &name)
has_any_suffix: see the rheostream page for the full documentation