Commit e318123ba7d7dfb05133dcdc482a35494f82350e

Authored by David Mayerich
1 parent 25d8d20b

changed stim::filename extensively, but the old class is available in filename_old.h

Showing 1 changed file with 448 additions and 0 deletions   Show diff stats
stim/parser/filename_old.h 0 → 100644
  1 +#ifndef STIM_FILENAME_H
  2 +#define STIM_FILENAME_H
  3 +
  4 +#include <stdio.h> /* defines FILENAME_MAX */
  5 +#ifdef _WIN32
  6 + #include <windows.h>
  7 + #include <direct.h>
  8 + #define GetCurrentDir _getcwd
  9 + #define STIM_FILENAME_DIV '/'
  10 +#else
  11 + #include <unistd.h>
  12 + #define GetCurrentDir getcwd
  13 + #define STIM_FILENAME_DIV '/'
  14 + #endif
  15 +
  16 +#include <string>
  17 +#include <sstream>
  18 +#include <iomanip>
  19 +#include <vector>
  20 +#include <stack>
  21 +#include <algorithm>
  22 +#include <iostream>
  23 +
  24 +#include "../parser/parser.h"
  25 +#ifdef BOOST_PRECOMPILED
  26 +#include <boost/filesystem.hpp>
  27 +#endif
  28 +namespace stim{
  29 +
  30 +//filename class designed to work with both Windows and Unix
  31 +
  32 +class filename{
  33 +
  34 +private:
  35 + void init(){
  36 +
  37 + absolute = false;
  38 +
  39 + }
  40 +
  41 +protected:
  42 +
  43 + std::string drive; //drive letter (for Windows)
  44 + std::vector<std::string> path; //directory hierarchy
  45 + std::string pref; //file prefix (without extension)
  46 + std::string ext; //file extension
  47 +
  48 + bool absolute; //filename is an absolute path
  49 +
  50 + //replaces win32 dividers with the Linux standard
  51 + std::string unix_div(std::string s) {
  52 + std::replace( s.begin(), s.end(), '\\', '/');
  53 + return s;
  54 + }
  55 +
  56 + //break up a filename into a prefix and extension
  57 + void parse_name(std::string fname){
  58 +
  59 + //find the extension
  60 + size_t xpos = fname.find_last_of('.'); //find the position of the extension period (if there is one)
  61 + if(xpos != std::string::npos){ //split the prefix and extension
  62 + pref = fname.substr(0, xpos);
  63 + ext = fname.substr(xpos + 1);
  64 + }
  65 + else
  66 + pref = fname;
  67 + }
  68 +
  69 + /// Parse a file locator into its component parts
  70 + void parse(std::string &dr, std::vector<std::string> &p, std::string &pre, std::string &ex, bool &abs, std::string loc){
  71 + dr = ""; //initialize the drive to NULL (in a Unix system, this will always be NULL)
  72 + p.clear(); //empty out the path array
  73 + pre = ""; //initialize the file prefix to NULL (if no file name is given, this will remain NULL)
  74 + ex = ""; //initialize the file extension to NULL (if no extension exists, this will remain NULL)
  75 + abs = false; //the default path is relative
  76 +
  77 + loc = unix_div(loc); //convert to unix style divisions (default representation)
  78 +
  79 + if(loc.size() == 0) return; //if the locator is NULL, just return (everything else will be NULL)
  80 +
  81 + //determine the drive (if Windows)
  82 + #ifdef _WIN32
  83 + if(loc[1] == ':'){ //if the second character is a colon, the character right before it is the drive
  84 + abs = true; //this is an absolute path
  85 + dr = loc[0]; //copy the drive letter
  86 + loc = loc.substr(3); //remove the drive information from the locator string
  87 + }
  88 + #else
  89 + if(loc[0] == STIM_FILENAME_DIV){
  90 + absolute = true;
  91 + loc = loc.substr(1);
  92 + }
  93 + #endif
  94 +
  95 + std::string fname = loc.substr( loc.find_last_of('/') + 1 ); //find the file name (including extension)
  96 +
  97 + //find the extension and prefix
  98 + size_t xpos = fname.find_last_of('.'); //find the position of the extension period (if there is one)
  99 + if(xpos != std::string::npos){ //split the prefix and extension
  100 + pre = fname.substr(0, xpos);
  101 + ex = fname.substr(xpos + 1);
  102 + }
  103 + else
  104 + pre = fname;
  105 + }
  106 +
  107 + //parse a file locator string
  108 + void parse(std::string loc){
  109 + if(loc.size() == 0) return;
  110 +
  111 + loc = unix_div(loc);
  112 +
  113 + //determine the drive (if Windows)
  114 + drive = "";
  115 + #ifdef _WIN32
  116 + //if the second character is a colon, the character right before it is the drive
  117 + if(loc[1] == ':'){
  118 + absolute = true; //this is an absolute path
  119 + drive = loc[0]; //copy the drive letter
  120 + loc = loc.substr(3); //remove the drive information from the locator string
  121 + }
  122 + #else
  123 + if(loc[0] == STIM_FILENAME_DIV){
  124 + absolute = true;
  125 + loc = loc.substr(1);
  126 + }
  127 + #endif
  128 +
  129 + //determine the file name
  130 + std::string fname = loc.substr( loc.find_last_of('/') + 1 ); //find the file name (including extension)
  131 +
  132 + //parse the file name
  133 + parse_name(fname);
  134 +
  135 + //find the directory hierarchy
  136 + std::string dir = loc.substr(0, loc.find_last_of('/') + 1 );
  137 + path = stim::parser::split(dir, '/');
  138 + }
  139 +
  140 +public:
  141 +
  142 + filename(){
  143 + init();
  144 + }
  145 +
  146 + filename(std::string loc){
  147 + init();
  148 + parse(loc);
  149 + }
  150 +
  151 +
  152 + /// Outputs the file name (including prefix and extension)
  153 + std::string get_name(){
  154 + if(pref == "" && ext == "")
  155 + return "";
  156 + else
  157 + return pref + "." + ext;
  158 + }
  159 +
  160 + /// Output the file extension only (usually three characters after a '.')
  161 + std::string get_extension(){
  162 + return ext;
  163 + }
  164 +
  165 + std::string extension(){
  166 + return ext;
  167 + }
  168 +
  169 + void extension(std::string e){
  170 + ext = e;
  171 + }
  172 +
  173 + /// Output the file prefix only (name before the extension)
  174 + std::string get_prefix(){
  175 + return pref;
  176 + }
  177 +
  178 + std::string prefix(){
  179 + return pref;
  180 + }
  181 +
  182 + void prefix(std::string p){
  183 + pref = p;
  184 + }
  185 +
  186 + /// Output the entire path (not including the filename)
  187 + /// ex. "c:\this\is\the\directory\"
  188 + std::string dir(){
  189 + std::stringstream ss;
  190 +
  191 + //if the path is absolute
  192 + if(absolute){
  193 + //output the drive letter if in Windows
  194 + #ifdef _WIN32
  195 + ss<<drive<<":";
  196 + #endif
  197 + ss<<STIM_FILENAME_DIV;
  198 + }
  199 +
  200 + //output the directory
  201 + for(unsigned int d = 0; d < path.size(); d++)
  202 + ss<<path[d]<<STIM_FILENAME_DIV;
  203 +
  204 + return ss.str();
  205 +
  206 + }
  207 +
  208 + void clear()
  209 + {
  210 + drive = ""; //drive letter (for Windows)
  211 + path.resize(0);
  212 + pref= ""; //file prefix (without extension)
  213 + ext = ""; //file extension
  214 + }
  215 +
  216 + /// Output the entire string, including the path and filename
  217 + /// ex. "c:\this\is\a\directory\file.txt"
  218 + std::string str(){
  219 + std::stringstream ss; //create a string stream
  220 + ss<<dir()<<get_name(); //push the directory and filename to that stream
  221 + return ss.str(); //convert the stream to a string and return it
  222 + }
  223 +
  224 + //*****************************************************************************************************************
  225 + // output is the directory and the prefix and the extension of the files, which are looking for in that directory.
  226 + /// David: I have no idea what this is doing. It looks identical to dir()
  227 + std::string dir_fname(){
  228 + std::stringstream ss;
  229 +
  230 + //if the path is absolute
  231 + if(absolute){
  232 + //output the drive letter if in Windows
  233 + #ifdef _WIN32
  234 + ss<<drive<<":";
  235 + #endif
  236 + ss<<STIM_FILENAME_DIV;
  237 + }
  238 +
  239 +
  240 + for(unsigned int d = 0; d < path.size(); d++)
  241 + ss<<path[d]<<STIM_FILENAME_DIV;
  242 + ss<<get_name();
  243 +
  244 + return ss.str();
  245 +
  246 + }
  247 +
  248 + // output is the directory and the name of the file which are found in that given directory
  249 + std::string f_name(std::string file_name){
  250 + std::stringstream ss;
  251 +
  252 + if(absolute){ //if the path is absolute
  253 + #ifdef _WIN32
  254 + ss<<drive<<":"; //output the drive letter if in Windows
  255 + #endif
  256 + ss<<STIM_FILENAME_DIV; //output a path divider
  257 + }
  258 +
  259 + for(unsigned int d = 0; d < path.size(); d++) //for each directory in the current path
  260 + ss<<path[d]<<STIM_FILENAME_DIV; //add that directory, interspersing path dividers
  261 +
  262 + stim::filename fn = file_name;
  263 + std::string fn_prefix = fn.pref;
  264 + std::string fn_ext = fn.ext;
  265 + ss<<fn_prefix + '.' + fn_ext;
  266 +
  267 + return ss.str();
  268 +
  269 + }
  270 +
  271 + /// Returns a list of files using the current filename as a template.
  272 + /// For example:
  273 + /// C:\this\is\a\path\file*.txt
  274 + /// can be used as a template to find a series of files file001.txt, file002.txt, file003.txt, etc.
  275 + std::vector<stim::filename> get_list(){
  276 + //this is OS dependent, so we're starting with Windows
  277 + //the Unix version requires Boost
  278 +
  279 +#ifdef _WIN32
  280 + stim::filename filepath(dir_fname()); //initialize filepath with the mask
  281 +
  282 + HANDLE hFind = INVALID_HANDLE_VALUE; //allocate data structures for looping through files
  283 + WIN32_FIND_DATAA FindFileData;
  284 + std::vector<stim::filename> file_list; //initialize a list to hold all matching filenames
  285 +
  286 + hFind = FindFirstFileA((filepath.str().c_str()), &FindFileData); //find the first file that matches the specified file path
  287 +
  288 + if (hFind == INVALID_HANDLE_VALUE) { //if there are no matching files
  289 + printf ("Invalid file handle. Error is %u.\n", GetLastError()); //print an error
  290 + }
  291 + else {
  292 + std::string file_name = FindFileData.cFileName; //save the file name
  293 + std::string file_path = dir(); //the file is in the specified directory, so save it
  294 + stim::filename current_file(file_path + file_name); //create a stim::filename structure representing this file
  295 + file_list.push_back(current_file); //push the new stim::filename to the file list
  296 +
  297 + // List all the other files in the directory.
  298 + while (FindNextFileA(hFind, &FindFileData) != 0){ //iterate until there are no more matching files
  299 + file_name = FindFileData.cFileName; //save the next file
  300 + current_file = (f_name(file_name)); //append the directory
  301 + file_list.push_back(current_file); //push it to the list
  302 + }
  303 + FindClose(hFind); //close the file data structure
  304 + }
  305 + return file_list; //return the list of files
  306 +
  307 +#elif BOOST_PRECOMPILED
  308 +
  309 + boost::filesystem::path p(dir()); //create a path from the current filename
  310 + std::vector<stim::filename> file_list;
  311 + if(boost::filesystem::exists(p)){
  312 + if(boost::filesystem::is_directory(p)){
  313 + typedef std::vector<boost::filesystem::path> vec; // store paths,
  314 + vec v; // so we can sort them later
  315 + std::copy(boost::filesystem::directory_iterator(p), boost::filesystem::directory_iterator(), back_inserter(v));
  316 + std::sort(v.begin(), v.end()); // sort, since directory iteration
  317 + // is not ordered on some file systems
  318 + //compare file names to the current template (look for wild cards)
  319 + for (vec::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it)
  320 + {
  321 + //if the filename is a wild card *or* it matches the read file name
  322 + if( prefix == "*" || prefix == (*it).filename().stem().string()){
  323 + //if the extension is a wild card *or* it matches the read file extension
  324 + if( ext == "*" || "." + ext == (*it).filename().extension().string()){
  325 + file_list.push_back((*it).string()); //include it in the final list
  326 + }
  327 +
  328 + }
  329 +
  330 +
  331 +
  332 + }
  333 +
  334 + }
  335 +
  336 + }
  337 + return file_list;
  338 +#else
  339 + std::cout<<"ERROR: UNIX systems don't support file lists without the Boost precompiled libraries."<<std::endl;
  340 + exit(1);
  341 +#endif
  342 +
  343 + }
  344 + //**************************************************************************************************
  345 +
  346 + //gets the current working directory
  347 + static stim::filename cwd(){
  348 +
  349 +
  350 + char cCurrentPath[FILENAME_MAX];
  351 +
  352 + if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath))){
  353 + std::cout<<"ERROR getting current working directory."<<std::endl;
  354 + exit(1);
  355 + }
  356 +
  357 + std::cout<<cCurrentPath<<std::endl;
  358 + return stim::filename(std::string(cCurrentPath) + STIM_FILENAME_DIV);
  359 + }
  360 +
  361 + void set_name(std::string fname){
  362 + parse_name(fname);
  363 + }
  364 +
  365 + //append a string to the filename and return a new filename
  366 + stim::filename append(std::string s){
  367 + stim::filename result = *this; //create a new filename, copy the current filename
  368 + result.pref = pref + s; //append the string to the filename
  369 + return result;
  370 + }
  371 +
  372 + //get a path relative to the current one
  373 + stim::filename get_relative(std::string rel){
  374 +
  375 + std::vector<std::string> rel_path = stim::parser::split(rel, STIM_FILENAME_DIV);
  376 +
  377 + //if the relative path doesn't contain a file, add a blank string to be used as the filename
  378 + if(rel[rel.size()-1] == STIM_FILENAME_DIV)
  379 + rel_path.push_back("");
  380 +
  381 + //create a stack representing the current absolute path
  382 + std::stack<std::string, std::vector<std::string> > s(path);
  383 +
  384 + //for each token in the relative path
  385 + for(int d=0; d<rel_path.size() - 1; d++){
  386 +
  387 + //if the token is a double-dot, pop a directory off of the stack
  388 + if(rel_path[d] == "..")
  389 + s.pop();
  390 + else
  391 + s.push(rel_path[d]);
  392 + }
  393 +
  394 + std::string* end = &s.top() + 1;
  395 + std::string* begin = end - s.size();
  396 + std::vector<std::string> result_path(begin, end);
  397 +
  398 + //create a new path to be returned
  399 + stim::filename result = *this;
  400 + result.path = result_path;
  401 + result.set_name(rel_path.back());
  402 +
  403 + return result;
  404 + }
  405 +
  406 + /// This function replaces a wildcard in the prefix with the specified string
  407 + stim::filename insert(std::string str){
  408 +
  409 + stim::filename result = *this; //initialize the result filename to the current filename
  410 + size_t loc = result.pref.find('*'); //find a wild card in the string
  411 + if(loc == std::string::npos) //if a wildcard isn't found
  412 + result.pref += str; //append the value to the prefix
  413 + else
  414 + result.pref.replace(loc, 1, str); //replace the wildcard with the string
  415 + return result; //return the result
  416 + }
  417 +
  418 + stim::filename insert(size_t i, size_t n = 2){
  419 +
  420 + std::stringstream ss;
  421 + ss << std::setw(n) << std::setfill('0') << i;
  422 + return insert(ss.str());
  423 + }
  424 +
  425 + bool is_relative(){
  426 + return !absolute;
  427 + }
  428 +
  429 + bool is_absolute(){
  430 + return absolute;
  431 + }
  432 +
  433 +
  434 +
  435 +
  436 +
  437 +
  438 +
  439 +
  440 +
  441 +};
  442 +
  443 +
  444 +} //end namespace stim
  445 +
  446 +
  447 +#endif
  448 +
... ...