bool create_directories(const path & p) { if(p.empty()) { return true; } path parent = p.parent(); if(!exists(parent)) { if(!create_directories(parent)) { return false; } } return create_directory(p); }
directory_iterator::directory_iterator(const path & p) : m_handle(INVALID_HANDLE_VALUE), m_buffer(NULL) { std::string searchPath = (p.empty() ? "." : p.string()) + "\\*"; WIN32_FIND_DATAW * data = new WIN32_FIND_DATAW; m_handle = FindFirstFileW(platform::WideString(searchPath), data); if(m_handle != INVALID_HANDLE_VALUE) { m_buffer = data; if(!wcscmp(data->cFileName, L".") || !wcscmp(data->cFileName, L"..")) { operator++(); } } else { delete data; } }
path absolute(const path& filename) { if ( !filename.empty() ) { #if (( defined( _POSIX_VERSION ) && _POSIX_VERSION >= 200809l ) || defined( __GLIBC__ )) // Preferred - POSIX-2008 and glibc will allocate the path buffer char* res = ::realpath(filename.c_str(), NULL); if ( res ) { path s = res; ::free(res); return s; } #else #ifdef _GNU_SOURCE // Maybe we can rely on the GNU extension char* res = ::canonicalize_file_name( filename.c_str() ); if ( res ) { std::string s = res; ::free(res); return s; } #elif ((( defined( _POSIX_VERSION ) && _POSIX_VERSION >= 200112L ) || ( defined( _XOPEN_VERSION ) && _XOPEN_VERSION >= 500 )) && defined( PATH_MAX )) /// @todo PATH_MAX may be huge or -1, according to man pages for realpath char resolved[PATH_MAX + 1]; char* res = ::realpath(filename.c_str(), resolved); if ( res ) { return resolved; } #else #error "No way to get absolute file path!" #endif // if 1 #endif // if ( defined( _POSIX_VERSION ) && _POSIX_VERSION >= 200809l ) } return path(); }
bool create_directory(const path & p) { if(p.empty()) { return true; } bool ret = CreateDirectoryA(p.string().c_str(), NULL) == TRUE; if(!ret) { int lastError = GetLastError(); ret = lastError == ERROR_ALREADY_EXISTS; if(!ret) { LogWarning << "CreateDirectoryA(" << p << ", NULL) failed! " << GetLastErrorString(); } } return ret; }
SharedPtrNotNULL<std::fstream> createFifo(const boost::filesystem::path &p) { // fifo cannot exist yet if( exists(p) ) throw ExceptionFilesystemIO(SYSTEM_SAVE_LOCATION, p, "exists", "element already exists"); // directory path must be sane const path parent=Base::Filesystem::parentPath(p); if( parent.empty()==false ) { if( isDirectorySane(parent)==false ) throw ExceptionFilesystemIO(SYSTEM_SAVE_LOCATION, p, "isDirectorySane", "path looks suspicious - refusing to create fifo"); } // create new fifo if( mkfifo( p.string().c_str(), 0644 )!=0 ) throw ExceptionFilesystemIO(SYSTEM_SAVE_LOCATION, p, "mkfifo", "unable to create fifo queue"); // opens fifo return openFifo(p); }
bool makeParentFolder(const path& p,const path& base,bool recursive) { // get path to last directory path wp(p); if (base.empty()) { wp = boost::filesystem::complete(wp); } else { wp = boost::filesystem::complete(wp,base); } if (wp.has_filename()) { wp = wp.parent_path(); } // make one or more directories as needed and as directed by recursive bool result = true; if (boost::filesystem::is_directory(wp)) { return result; } else if (recursive) { try { result = create_directories(wp); } catch (...) { result = false; } } else { try { result = create_directory(wp); } catch (...) { result = false; } } return result; }
std::string get_cache_dir() { if (cache_dir.empty()) { #if defined(_X11) && !defined(PREFERENCES_DIR) char const *xdg_cache = getenv("XDG_CACHE_HOME"); if (!xdg_cache || xdg_cache[0] == '\0') { xdg_cache = getenv("HOME"); if (!xdg_cache) { cache_dir = get_dir(get_user_data_path() / "cache"); return cache_dir.string(); } cache_dir = xdg_cache; cache_dir /= ".cache"; } else cache_dir = xdg_cache; cache_dir /= "wesnoth"; create_directory_if_missing_recursive(cache_dir); #else cache_dir = get_dir(get_user_data_path() / "cache"); #endif } return cache_dir.string(); }
std::string get_user_config_dir() { if (user_config_dir.empty()) { #if defined(_X11) && !defined(PREFERENCES_DIR) char const *xdg_config = getenv("XDG_CONFIG_HOME"); if (!xdg_config || xdg_config[0] == '\0') { xdg_config = getenv("HOME"); if (!xdg_config) { user_config_dir = get_user_data_path(); return user_config_dir.string(); } user_config_dir = xdg_config; user_config_dir /= ".config"; } else user_config_dir = xdg_config; user_config_dir /= "wesnoth"; set_user_config_path(user_config_dir); #else user_config_dir = get_user_data_path(); #endif } return user_config_dir.string(); }
path completeAndNormalize(const path& p) { path temp = boost::filesystem::system_complete(p); if (temp.empty() && !p.empty()) { temp = p; } path result; for(openstudio::path::iterator it=temp.begin(); it!=temp.end(); ++it) { if (*it == toPath("..")) { if (boost::filesystem::is_symlink(result) || (result.filename() == toPath(".."))) { result /= *it; } else { result = result.parent_path(); } } else if(*it != toPath(".")) { result /= *it; } } return result; }
void HTMLEditor::Save(const path & path) { if (path.empty()) { throw runtime_error("Path cannot be empty!"); } if (path.has_parent_path()) { create_directories(path.parent_path()); } std::ofstream file(path.generic_string()); if (!file.is_open()) { throw runtime_error("Invalid path specified" + path.generic_string()); } file << "<!DOCTYPE html>\n<html>\n<head>\n\t<title>" << EncodeHtmlStr(m_document.GetTitle()) << "</title>\n</head>\n" << "<body>\n" << CreateBody(path) << "</body>\n</html>"; file.close(); }
path path::resolve(const path & a, const path & b) { if(a.empty()) { return b; } size_t bpos = 0; size_t apos = a.pathstr.length(); while(true) { size_t dirpos = a.pathstr.find_last_of(dir_sep, apos - 1); if(dirpos == std::string::npos) { if(bpos + 3 >= b.pathstr.length()) { return path(); } else { return b.pathstr.substr(bpos + 3); } } if(is_path_up(a.pathstr, dirpos + 1)) { return path(a.pathstr.substr(0, apos) + dir_sep + b.pathstr.substr(bpos)); } apos = dirpos, bpos += 3; if(!is_path_up(b.pathstr, bpos)) { if(bpos >= b.pathstr.length()) { return path(a.pathstr.substr(0, apos)); } else { return path(a.pathstr.substr(0, apos) + dir_sep + b.pathstr.substr(bpos)); } } } }
static bool create_directory_if_missing_recursive(const path& dirpath) { DBG_FS << "creating recursive directory: " << dirpath.string() << '\n'; if (dirpath.empty()) return false; error_code ec; bfs::file_status fs = bfs::status(dirpath); if (error_except_not_found(ec)) { ERR_FS << "Failed to retrieve file status for " << dirpath.string() << ": " << ec.message() << '\n'; return false; } else if (bfs::is_directory(fs)) { return true; } else if (bfs::exists(fs)) { return false; } if (!dirpath.has_parent_path() || create_directory_if_missing_recursive(dirpath.parent_path())) { return create_directory_if_missing(dirpath); } else { ERR_FS << "Could not create parents to " << dirpath.string() << '\n'; return false; } }
directory_iterator::directory_iterator(const path & p) : buf(NULL) { handle = DIR_HANDLE_INIT(p, opendir(p.empty() ? "./" : p.string().c_str())); if(DIR_HANDLE(handle)) { // Allocate a large enough buffer for readdir_r. long name_max; #if ((defined(ARX_HAVE_DIRFD) && defined(ARX_HAVE_FPATHCONF)) || defined(ARX_HAVE_PATHCONF)) \ && defined(ARX_HAVE_PC_NAME_MAX) # if defined(ARX_HAVE_DIRFD) && defined(ARX_HAVE_FPATHCONF) name_max = fpathconf(dirfd(DIR_HANDLE(handle)), _PC_NAME_MAX); #else name_max = pathconf(p.string().c_str(), _PC_NAME_MAX); #endif if(name_max == -1) { # if defined(ARX_HAVE_NAME_MAX) name_max = std::max(NAME_MAX, 255); # else arx_assert_msg(false, "cannot determine maximum dirname size"); # endif } #elif defined(ARX_HAVE_NAME_MAX) name_max = std::max(NAME_MAX, 255); #else # error "buffer size for readdir_r cannot be determined" #endif size_t size = (size_t)offsetof(dirent, d_name) + name_max + 1; if(size < sizeof(dirent)) { size = sizeof(dirent); } buf = malloc(size); readdir(handle, buf); } };
static path findUserPath(const char * name, const path & force, const char * registry, platform::SystemPathId systemPathId, const char * prefix, const char * suffix, const path & fallback, bool create) { // Prefer command-line options if(!force.empty()) { path dir = canonical(force); if(create && !create_directories(dir)) { LogCritical << "Could not create " << name << " directory " << dir << '.'; return path(); } else { LogDebug("using " << name << " dir from command-line: " << dir); return dir; } } // Check system settings (windows registry) std::string temp; if(registry && platform::getSystemConfiguration(registry, temp)) { path dir = canonical(temp); if(!create) { return dir; } else if(create_directories(dir)) { LogDebug("got " << name << " dir from registry: \"" << temp << "\" = " << dir); return dir; } else { LogError << "Could not create " << name << " directory " << dir << '.'; LogDebug("ignoring " << name << " dir from registry: \"" << temp << '"'); } } // Search standard locations path to_create; std::vector<path> prefixes = getSearchPaths(prefix); std::vector<path> suffixes = getSearchPaths(suffix); if(!suffixes.empty()) { std::vector<path> paths = platform::getSystemPaths(systemPathId); prefixes.insert(prefixes.end(), paths.begin(), paths.end()); } bool create_exists = false; BOOST_FOREACH(const path & prefix, prefixes) { BOOST_FOREACH(const path & suffix, suffixes) { path dir = canonical(prefix / suffix); if(is_directory(dir)) { LogDebug("got " << name << " dir from search: " << prefix << " + " << suffix << " = " << dir); return dir; } else { LogDebug("ignoring " << name << " dir from search: " << prefix << " + " << suffix << " = " << dir); } if(to_create.empty() || (!create_exists && is_directory(prefix))) { to_create = dir; create_exists = is_directory(prefix); } }
/// \brief Attempt to parse the specified options /// /// \pre All previously added options_blocks must still exist /// /// \pre The two parameters must be in the standard argc/argv configuration /// /// Note that the two input parameters are taken const /// (including the argv being (a pointer to) an array of const pointers *to const*) /// so they will remain untouched. /// /// \post The options will be parsed and ready for querying void executable_options::parse_options(const int &argc, ///< The argc from command line parameters const char * const argv[] ///< The argv from command line parameters ) { // Check the options haven't already been processed if (processed_options) { BOOST_THROW_EXCEPTION(invalid_argument_exception("Cannot process options once they have already been processed")); } // Create two options_description, one complete and another containing all visible options options_description full_po_desc ( DEFAULT_PROG_OPS_LINE_LENGTH ); options_description visible_po_desc( DEFAULT_PROG_OPS_LINE_LENGTH ); // Frustratingly, Boost 1.41 (as used by orengobuild64) won't accept a const argv, so // it's necessary to construct a fake argc/argv here argc_argv_faker fake_argc_argv(argc, argv); int new_argc = fake_argc_argv.get_argc(); char * * new_argv = fake_argc_argv.get_argv(); // Add each of the options_blocks to po_desc for (options_block * const options_block_ptr : all_options_blocks) { const options_description hidden_opts = options_block_ptr->get_hidden_options_description( DEFAULT_PROG_OPS_LINE_LENGTH ); const options_description visible_opts = options_block_ptr->get_visible_options_description( DEFAULT_PROG_OPS_LINE_LENGTH ); full_po_desc.add( hidden_opts ); full_po_desc.add( visible_opts ); visible_po_desc.add( visible_opts ); } // Attempt the parses and catch any exceptions // // The parses are performed in decreasing order of precedence // (ie options specified via the command line should take precedence over those // specified via environment variables so it comes first) // // \todo If this gets any more complicated then consider putting each of these // different parses into different objects (presumably of classes deriving from // a single ABC). string parsing_approach = ""; try { // Parse options from the command line parsing_approach = "from the command line"; const positional_options_description positionals = get_positional_options(); processed_options = true; store( command_line_parser( new_argc, new_argv ).options( full_po_desc ).positional( positionals ).run(), vm ); // Parse any environment variables prefixed with "CATH_TOOLS_" // and just silently ignore any unknown options parsing_approach = "from global environment variables with prefix " + CATH_TOOLS_ENVIRONMENT_VARIABLE_PREFIX; //! [Using env_var_option_name_handler] store( parse_environment( full_po_desc, env_var_option_name_handler( CATH_TOOLS_ENVIRONMENT_VARIABLE_PREFIX, true, full_po_desc ) ), vm ); //! [Using env_var_option_name_handler] // Parse any configuration file called cath_tools.conf const path located_cath_tools_conf_file = find_file(CATH_TOOLS_CONF_FILE_SEARCH_PATH, CATH_TOOLS_CONF_FILE.string()); if (!located_cath_tools_conf_file.empty()) { // cerr << "Parsing configuration from file " << CATH_TOOLS_CONF_FILE << endl; parsing_approach = "from the global configuration file " + located_cath_tools_conf_file.string(); ifstream config_file_stream; open_ifstream(config_file_stream, CATH_TOOLS_CONF_FILE); store(parse_config_file(config_file_stream, full_po_desc, true), vm); config_file_stream.close(); } // All parsing is complete so call notify, which will trigger any // post-parsing hooks to get called notify(vm); } catch (std::exception &e) { error_or_help_string = get_program_name() + ": Error in parsing program options (" + parsing_approach + "): " + e.what(); } catch (...) { error_or_help_string = get_program_name() + ": Caught an unrecognised exception whilst parsing program options (" + parsing_approach + ").\n"; } // If no error has yet been encountered // and if any of the blocks return non-empty invalid_string() results, // then set error_or_help_string to the first if (error_or_help_string.empty()) { for (options_block * const options_block_ptr : all_options_blocks) { const opt_str block_invalid_string = options_block_ptr->invalid_string(); if ( block_invalid_string ) { error_or_help_string = *block_invalid_string; break; } } } // If an error string has already arisen from the parsing or from an options block being invalid... if (!error_or_help_string.empty()) { // ...and if doesn't already end with the standard usage error string // (eg "Try 'cath-ssap --help' for usage information.") // then append it now. if (!ends_with(error_or_help_string, get_standard_usage_error_string())) { error_or_help_string += ("\n" + get_standard_usage_error_string()); } } // Else there is no error string yet, so now let the derived class consider then // set it to whatever the derived class decides else { error_or_help_string = do_update_error_or_help_string( visible_po_desc ); } }
path lexically_normal(const path& p) { if (p.empty()) return p; path temp; path::iterator start(p.begin()); path::iterator last(p.end()); path::iterator stop(last--); for (path::iterator itr(start); itr != stop; ++itr) { // ignore "." except at start and last if (itr->native().size() == 1 && (itr->native())[0] == dot && itr != start && itr != last) continue; // ignore a name and following ".." if (!temp.empty() && itr->native().size() == 2 && (itr->native())[0] == dot && (itr->native())[1] == dot) // dot dot { string_type lf(temp.filename().native()); if (lf.size() > 0 && (lf.size() != 1 || (lf[0] != dot && lf[0] != separator)) && (lf.size() != 2 || (lf[0] != dot && lf[1] != dot # ifdef BOOST_WINDOWS_API && lf[1] != colon # endif ) ) ) { temp.remove_filename(); //// if not root directory, must also remove "/" if any //if (temp.native().size() > 0 // && temp.native()[temp.native().size()-1] // == separator) //{ // string_type::size_type rds( // root_directory_start(temp.native(), temp.native().size())); // if (rds == string_type::npos // || rds != temp.native().size()-1) // { // temp.m_pathname.erase(temp.native().size()-1); // } //} path::iterator next(itr); if (temp.empty() && ++next != stop && next == last && *last == detail::dot_path()) { temp /= detail::dot_path(); } continue; } } temp /= *itr; }; if (temp.empty()) temp /= detail::dot_path(); return temp; }