diff --git a/pub/CHANGELOG b/pub/CHANGELOG index 151c764be688d8f05fc82fb9997c13a13888a10a..9e4afe41bf54e93c38732573e6bdf830cf0f274d 100644 --- a/pub/CHANGELOG +++ b/pub/CHANGELOG @@ -1,6 +1,14 @@ -- New commands gP gF to impose graphic file name -- New integral operations firstwith, lastwith -- Integral operations now return integers when appropriate +Release 2.3.6a of : + +- Bug fixes: + - Restored ability to load files from outside the current working directory +- New functionality: + - New integral operations firstwith, lastwith +- Improved functionality: + - Commands gp, gf let user confirm or overwrite graphic file name + - Integral operations now return integers when appropriate +- Code cleanup: + - fname_divide replaced by functions from std::experimental::filesystem Release 2.3.5a of 01feb17: diff --git a/pub/CMakeLists.txt b/pub/CMakeLists.txt index e8e9cde6ad625fdcb2574d02168ab36afa02e93d..aeabe98bc2b185699b0b796dda50295faf6acbc5 100644 --- a/pub/CMakeLists.txt +++ b/pub/CMakeLists.txt @@ -27,7 +27,7 @@ set(destination_lib ${CMAKE_INSTALL_PREFIX}/lib) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -O2 -pedantic -Wall -Wno-sign-compare -Wno-unused-result -Wno-parentheses -Wno-unknown-pragmas -Werror") # to use C99 _Complex, add -fext-numeric-literals to CXX_FLAGS -find_package(Boost REQUIRED) # used header-only modules: format algorithm +find_package(Boost REQUIRED) # we need no binary COMPONENTS, but the headers format, algorithm find_package(BISON REQUIRED) find_package(FLEX REQUIRED) find_package(Readline REQUIRED) diff --git a/pub/lib/commands.cpp b/pub/lib/commands.cpp index ed8557a37a7aa20e5d44568756cf9bc8a838bfd4..64b601bb04986ce3d19b4f9af47fba48bf4772a4 100644 --- a/pub/lib/commands.cpp +++ b/pub/lib/commands.cpp @@ -11,6 +11,7 @@ #include "ptr.hpp" #include <cstring> +#include <experimental/filesystem> #include "../plot/dualplot.hpp" #include "../plot/plowin.hpp" @@ -41,6 +42,9 @@ #include "commands.hpp" +namespace fs = std::experimental::filesystem; + + //! Executes cmd if is a Frida command, and returns true when successful. bool frida_command(string cmd) @@ -358,12 +362,12 @@ bool frida_command(string cmd) static string fname = ""; if (cmd != "gfa") { string defaultname = triv::next_tmp_file( - CNode::eval("psdir")->to_s() + (ps_dict == "" ? "l" : "L") + "%i"); - string fdir, fshort; - triv::fname_divide(defaultname, &fdir, &fshort, nullptr); - defaultname = fshort; + CNode::eval("psdir")->to_s() + (ps_dict == "" ? "l" : "L") + "%i" + ext); + defaultname = fs::path(defaultname).stem(); fname = sask("Graphic file name (without extension "+ext+")", defaultname); - if (fname!="") + if (fname=="") + return false; + if (fs::path(fname).extension()=="") fname += ext; } else fname = sask("Graphic file name", fname); diff --git a/pub/lib/file_in.cpp b/pub/lib/file_in.cpp index c9622be9f1cf5b005f32373dd6c9c91ea5263e09..f4b3e5a3b7682c92ac9a6876fc8a01a565b41c48 100644 --- a/pub/lib/file_in.cpp +++ b/pub/lib/file_in.cpp @@ -11,7 +11,7 @@ #include <fstream> #include <string.h> - +#include <experimental/filesystem> #include <yaml-cpp/yaml.h> #include "../readplus/ask.hpp" @@ -24,14 +24,15 @@ #include "olf.hpp" #include "slice.hpp" +namespace fs = std::experimental::filesystem; + namespace NFileIn { -void Load_yda(std::ifstream& F_in, string fnam); -void Load_08(std::ifstream& F_in, string flong); -void Load_01(FILE* F_in, string flong); +void Load_yda(std::ifstream& F_in, string fshort); +void Load_01(FILE* F_in, string fshort); void LoadSpec_01(FILE* F_in, PSpec& sout, int nz); -void Load_96(FILE* F_in, string flong); +void Load_96(FILE* F_in, string fshort); } @@ -42,30 +43,30 @@ void NFileIn::load(void) string pattern = sask("Load file(s)"); vector<string> fNames = triv::glob_file_list(pattern, "yda y08 a01 i96"); if (!fNames.size()) - throw "Found no files that match the pattern '" + pattern + "'"; + throw "Found no file that matches '" + pattern + "'"; for (string fnam : fNames) { try { - string fdir, fshort, fext; - triv::fname_divide(fnam, &fdir, &fshort, &fext); - if (fext == "y08" || fext == "yda") { + string fext = fs::path(fnam).extension(); + string fshort = fs::path(fnam).filename().stem(); + if (fext == ".y08" || fext == ".yda") { std::ifstream FS(fnam.c_str(), std::ios_base::in); if (FS.fail()) throw string("cannot open file"); cout << ".. loading file " << fnam << "\n"; Load_yda(FS, fshort); FS.close(); - } else if (fext == "a01" || fext == "i96") { + } else if (fext == ".a01" || fext == ".i96") { FILE* F_in; if (!(F_in = fopen(fnam.c_str(), "r"))) throw "cannot open file " + fnam; - if (fext == "a01") { - Load_01(F_in, fnam.c_str()); - } else if (fext == "i96") { - Load_96(F_in, fnam.c_str()); + if (fext == ".a01") { + Load_01(F_in, fshort); + } else if (fext == ".i96") { + Load_96(F_in, fshort); } fclose(F_in); } else - throw "unknown extension " + fext; + throw "unknown extension '" + fext + "'"; } catch (string& ex) { throw "Cannot load " + fnam + ": " + ex; } catch (std::exception& ex) { @@ -76,7 +77,7 @@ void NFileIn::load(void) //! Load a YAML file in yda format. -void NFileIn::Load_yda(std::ifstream& FS, string fnam) +void NFileIn::Load_yda(std::ifstream& FS, string fshort) { const YAML::Node doc = YAML::Load(FS); if (doc.Type() != YAML::NodeType::Map) @@ -351,7 +352,7 @@ void NFileIn::Load_yda(std::ifstream& FS, string fnam) } } - fout->name = fnam; + fout->name = fshort; fout->as_on_disk = true; SMem::instance()->mem_store(move(fout)); } @@ -359,15 +360,13 @@ void NFileIn::Load_yda(std::ifstream& FS, string fnam) //! Load a .a01 formatted file. -void NFileIn::Load_01(FILE* F_in, string flong) +void NFileIn::Load_01(FILE* F_in, string fshort) { - string lin, key, val, fdir, fshort, fext; + string lin, key, val; int iz, nj = 0, j; CCoord co; POld fout(new COld); - triv::fname_divide(flong, &fdir, &fshort, &fext); - if (triv::freadln(F_in, &lin) <= 0) throw "file empty or starting with empty line"; if (lin != string("ASCII-01 JWu")) @@ -486,16 +485,15 @@ void NFileIn::LoadSpec_01(FILE* F_in, PSpec& sout, int nz) //! Load a .i96 formatted file. -void NFileIn::Load_96(FILE* F_in, string flong) +void NFileIn::Load_96(FILE* F_in, string fshort) { - string lin, key, val, fdir, fshort, fext; + string lin, key, val; double r0, r1, r2; int n, nspec, ival; POld fout(new COld); CCoord co; PSpec sout; - triv::fname_divide(flong, &fdir, &fshort, &fext); fout->name = fshort; if (!triv::freadln(F_in, &lin)) diff --git a/pub/lib/import.cpp b/pub/lib/import.cpp index aebe61b6114f801d3d9b6a933695650d2eea0a97..03af1968d7958aa14708659370de0ef80365c557 100644 --- a/pub/lib/import.cpp +++ b/pub/lib/import.cpp @@ -7,8 +7,9 @@ //! \file import.cpp //! \brief NImport: import tables or make data ex nihilo -#include "defs.hpp" +#include <experimental/filesystem> +#include "defs.hpp" #include "../readplus/ask.hpp" #include "../trivia/file_ops.hpp" @@ -20,6 +21,8 @@ #include "olf.hpp" #include "slice.hpp" +namespace fs = std::experimental::filesystem; + //! Create a new online file from table. @@ -63,7 +66,6 @@ void NImport::read_tab(string qualif) } FILE* fd; - string fdir, fshort, fext; for (int iF = 0; iF < inFiles.size(); ++iF) { if (!(fd = fopen(inFiles[iF].c_str(), "r"))) throw "cannot open file " + inFiles[iF]; @@ -73,9 +75,8 @@ void NImport::read_tab(string qualif) fout->log_action("ft" + qualif + " " + script); fout->name = script; } else { - triv::fname_divide(inFiles[iF], &fdir, &fshort, &fext); fout->log_action("ft" + qualif + " " + inFiles[iF]); - fout->name = fshort; + fout->name = fs::path(inFiles[iF]).filename().stem(); if (choosecol) { fout->log_action("y from column " + S(iycol)); fout->name += "_" + S(iycol); diff --git a/pub/lib/rssm.cpp b/pub/lib/rssm.cpp index c45e4ae7e24fccbdf04efb83fd927eb552c63cb4..d8ad3a42fb1054d5a3ed7c7d16005fb5c5973972 100644 --- a/pub/lib/rssm.cpp +++ b/pub/lib/rssm.cpp @@ -11,11 +11,10 @@ #include <cstring> #include <fstream> - +#include <experimental/filesystem> #include <yaml-cpp/yaml.h> #include "../readplus/ask.hpp" -#include "../trivia/file_ops.hpp" #include "../trivia/string_ops.hpp" #include "mem.hpp" @@ -24,6 +23,8 @@ #include "rssm.hpp" #include "slice.hpp" +namespace fs = std::experimental::filesystem; + //! All relevant information extracted from one raw-data file from SPHERES. @@ -223,8 +224,7 @@ void NRSSM::read_spec(int flag) // 16 no normalization { - string file_f, name; - file_f = wask("Read SPHERES data from file"); + string file_f = wask("Read SPHERES data from file"); CRawfileSpheres R; std::ifstream F_in; @@ -247,7 +247,7 @@ void NRSSM::read_spec(int flag) olf[iolf]->yco = CCoord("cts", "sec-1"); olf[iolf]->ZCo.push_back(CCoord("det", "")); } - triv::fname_divide(file_f, 0, &name, 0); + string name = fs::path(file_f).filename().stem(); olf[0]->name = name + "left"; olf[1]->name = name + "right"; olf[2]->name = name + "open_left"; @@ -379,7 +379,7 @@ void NRSSM::read_series(int flag) { char tstrg[30]; - string fser, fnam, name; + string fser, fnam; time_t t; int isub; vector<CRawfileSpheres> RR; @@ -446,7 +446,7 @@ void NRSSM::read_series(int flag) olf[iolf]->ZCo.push_back(CCoord("#sub", "")); olf[iolf]->ZCo.push_back(CCoord("det", "")); } - triv::fname_divide(fser, 0, &name, 0); + string name = fs::path(fser).filename().stem(); olf[0]->name = name; olf[1]->name = name + "open"; olf[0]->log_action("refl, average over both halfspaces"); diff --git a/pub/trivia/CMakeLists.txt b/pub/trivia/CMakeLists.txt index de0ce03c4f1e08b0dcd10510a66c07be88c07954..4a63cdb7ee1dcd94c2560444dd3bb689190bdd1a 100644 --- a/pub/trivia/CMakeLists.txt +++ b/pub/trivia/CMakeLists.txt @@ -36,6 +36,7 @@ set_target_properties(${library_name} PROPERTIES OUTPUT_NAME ${library_name}) target_link_libraries(${library_name} ${GSL_LIBRARIES} ${YAMLCPP_LIBRARY} + stdc++fs ) install(TARGETS ${library_name} LIBRARY DESTINATION ${destination_lib} COMPONENT Libraries) diff --git a/pub/trivia/file_ops.cpp b/pub/trivia/file_ops.cpp index 34dfedc67553660ec780926672712080c1d73d5c..7f138e4202cf69fbc3fdbd64b70a2b348389fb3c 100644 --- a/pub/trivia/file_ops.cpp +++ b/pub/trivia/file_ops.cpp @@ -7,10 +7,11 @@ #include <sys/stat.h> #include <wordexp.h> - #include <iostream> - #include <boost/format.hpp> +#include <experimental/filesystem> + +namespace fs = std::experimental::filesystem; using boost::format; using std::string; @@ -76,29 +77,6 @@ bool triv::file_exists(const string& path) return 1; } -//! Analyses a file name: divides "dir/short.ext" into "dir", "short", "ext". - -void triv::fname_divide(const string& fname, string* fdir, string* fshort, string* fext) -// each of the three output arguments, when called with a nullptr, will not be computed -{ - size_t idir = fname.rfind("/") + 1; - if (fdir) - *fdir = fname.substr(0, idir); - - size_t iext = fname.rfind(string(".")) + 1; - if (iext <= idir) { - if (fext) - *fext = ""; - if (fshort) - *fshort = fname.substr(idir); - } else { - if (fext) - *fext = fname.substr(iext); - if (fshort) - *fshort = fname.substr(idir, iext - idir - 1); - } -} - //! Returns a unique file name obtained by Posix shell expansion of a given pattern. @@ -175,8 +153,7 @@ vector<string> triv::glob_file_list(const string& patterns, const string& extens throw string("empty file list"); vector<string> vExtension = split(extensions); for (string pat : vPattern) { - string fmain, fext; - fname_divide(pat, nullptr, &fmain, &fext); + string fext = fs::path(pat).extension(); if (fext == "" && vExtension.size()) { for (string ext : vExtension) extended_patterns += pat + "." + ext + " "; diff --git a/pub/trivia/file_ops.hpp b/pub/trivia/file_ops.hpp index ee9a1e22201f210196ad4f9abe5530f59423470c..59b37dad2df31c875563372fd9962646b722a02a 100644 --- a/pub/trivia/file_ops.hpp +++ b/pub/trivia/file_ops.hpp @@ -17,8 +17,6 @@ std::string system_read(std::string cmd, bool debug = false); // File names, globbing: bool file_exists(const std::string& fname); -void fname_divide( - const std::string& fname, std::string* fdir, std::string* fshort, std::string* fext); std::vector<std::string> glob_file_list(const std::string& patterns, const std::string& extensions); std::string wordexp_unique(const std::string& s); std::vector<std::string> wordexp_multi(const std::string& s);