All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sbndcode/sbndcode/gallery/helpers/expandInputFiles.h
Go to the documentation of this file.
1 /**
2  * @file expandInputFiles.h
3  * @brief Function to expand file lists.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date October 19, 2017
6  *
7  * This header does not require an implementation file
8  * (only for convenience reasons).
9  *
10  */
11 
12 #ifndef EXPANDINPUTFILES_H
13 #define EXPANDINPUTFILES_H
14 
15 // C/C++ libraries
16 // <filesystem> is present from GCC 8 and CLANG 6, and as experimental from GCC 6;
17 // but linking to these is still a mess, so until we get word from the compiler
18 // that <filesystem> is available, we just don't use any (not even experimental)
19 #if __cpp_lib_filesystem
20 # define HAS_STD_FILESYSTEM 1
21 # include <filesystem> // std::filesystem::path
22 #else
23 # define HAS_STD_FILESYSTEM 0
24 #endif
25 
26 #include <fstream>
27 #include <cctype> // std::isspace()
28 #include <vector>
29 #include <stdexcept> // std::runtime_error
30 #include <string>
31 
32 
33 namespace details {
34 
35  template <typename T>
36  std::vector<T>& appendToVector
37  (std::vector<T>& dest, std::vector<T> const& src)
38  { dest.insert(dest.end(), src.begin(), src.end()); return dest; }
39 
40  template <typename StartIter, typename EndIter>
41  StartIter skipSpaces(StartIter begin, EndIter end) {
42  for (auto i = begin; i != end; ++i) if (!std::isspace(*i)) return i;
43  return end;
44  } // skipSpaces()
45 
46 
47  struct FileListExpansionBaseError: public std::runtime_error
48  { using std::runtime_error::runtime_error; };
49 
50  struct FileNotFoundError: public FileListExpansionBaseError {
51  FileNotFoundError(std::string const& fileName)
52  : FileListExpansionBaseError("Can't open file '" + fileName + "'")
53  {}
54  };
55 
56  struct FileListErrorWrapper: public FileListExpansionBaseError {
57  FileListErrorWrapper(std::string const& fileName, unsigned int line)
58  : FileListExpansionBaseError(formatMsg(fileName, line))
59  {}
61  std::string const& fileName, unsigned int line,
63  )
65  (std::string(error.what()) + "\n " + formatMsg(fileName, line))
66  {}
67 
68  private:
69  static std::string formatMsg(std::string const& fname, unsigned int line)
70  { return "Error from file list '" + fname + "' line " + std::to_string(line); }
71  };
72 
73 } // namespace details
74 
75 /// Returns whether the specified path represents a file list.
76 #if HAS_STD_FILESYSTEM
77 inline bool isROOTfile(std::filesystem::path const& filePath)
78  { return (filePath.extension() == ".root") && !filePath.stem().empty(); }
79 #else // no STL filesystem library:
80 inline bool isROOTfile(std::string const& filePath) {
81  if (filePath.length() < 6) return false; // too short (".root" is not good!)
82 
83  auto iExt = filePath.rfind('.');
84  if (iExt == std::string::npos) return false; // no file extension
85 
86  auto iBaseName = filePath.rfind('/');
87  if ((iBaseName != std::string::npos) && (iBaseName > iExt))
88  return false; // still no extension
89 
90  return filePath.substr(iExt) == ".root";
91 } // isROOTfile()
92 
93 #endif // STL filesystem library?
94 
95 /// Expands the content of a file list into a vector of file paths (recursive).
96 inline std::vector<std::string> expandFileList(std::string const& listPath) {
97 
98  std::ifstream list(listPath);
99  if (!list) throw details::FileNotFoundError(listPath);
100 
101  std::vector<std::string> files;
102  std::string line;
103  unsigned int iLine = 0;
104  do {
105  ++iLine; // currently unused
106  std::getline(list, line);
107  if (!list) break;
108 
109  auto const end = line.cend();
110 
111  //
112  // find the start of the file name
113  //
114  auto i = details::skipSpaces(line.cbegin(), end);
115  if (i == end) continue; // empty line
116  if (*i == '#') continue; // full comment line
117 
118  std::string filePath;
119  auto iChunk = i;
120  while(i != end) {
121  if (*i == '\\') {
122  filePath.append(iChunk, i); iChunk = i;
123  if (++i == end) break; // weird way to end a line, with a '\'
124  if ((*i == '\\') || (*i == '#')) iChunk = i; // eat the backspace
125  // the rest will be added with the next chuck
126  }
127  else if (std::isspace(*i)) {
128  filePath.append(iChunk, i); iChunk = i; // before, there were no spaces
129  auto const iAfter = details::skipSpaces(i, end);
130  if (iAfter == end) break; // spaces, then end of line: we are done
131  if (*iAfter == '#') break; // a comment starts after spaces: we are done
132  i = iAfter; // these spaces are part of file name; schedule for writing
133  continue;
134  }
135  ++i;
136  } // for
137  filePath.append(iChunk, i);
138  if (filePath.empty()) continue;
139 
140  if (isROOTfile(filePath))
141  files.push_back(filePath);
142  else {
143  try {
144  details::appendToVector(files, expandFileList(filePath));
145  }
146  catch(details::FileListExpansionBaseError const& e) {
147  throw details::FileListErrorWrapper(listPath, iLine, e);
148  }
149  }
150 
151  } while (true);
152  return files;
153 } // expandFileList()
154 
155 
156 /// Expands all input files into a vector of file paths.
157 inline std::vector<std::string> expandInputFiles
158  (std::vector<std::string> const& filePaths)
159 {
160  std::vector<std::string> expanded;
161  for (std::string const& path: filePaths) {
162  if (isROOTfile(path))
163  expanded.push_back(path);
164  else
166  } // for
167  return expanded;
168 } // expandInputFiles()
169 
170 
171 #endif // EXPANDINPUTFILES_H
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
string fname
Definition: demo.py:5
bool isROOTfile(std::string const &filePath)
Returns whether the specified path represents a file list.
FileListErrorWrapper(std::string const &fileName, unsigned int line, FileListExpansionBaseError const &error)
static std::string formatMsg(std::string const &fname, unsigned int line)
BEGIN_PROLOG triggeremu_data_config_icarus settings PMTADCthresholds sequence::icarus_stage0_multiTPC_TPC physics sequence::icarus_stage0_EastHits_TPC physics sequence::icarus_stage0_WestHits_TPC physics producers purityana0 caloskimCalorimetryCryoE physics caloskimCalorimetryCryoW physics path
std::vector< std::string > expandInputFiles(std::vector< std::string > const &filePaths)
Expands all input files into a vector of file paths.
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
std::vector< T > & appendToVector(std::vector< T > &dest, std::vector< T > const &src)
std::vector< std::string > expandFileList(std::string const &listPath)
Expands the content of a file list into a vector of file paths (recursive).
FileListErrorWrapper(std::string const &fileName, unsigned int line)
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
std::string to_string(WindowPattern const &pattern)
do i e
list
Definition: file_to_url.sh:28
StartIter skipSpaces(StartIter begin, EndIter end)