예제 #1
0
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);
}
예제 #2
0
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;
	}
	
}
예제 #3
0
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;
}
예제 #5
0
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);
}
예제 #6
0
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;
}
예제 #7
0
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();
}
예제 #8
0
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();
}
예제 #9
0
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;
}
예제 #10
0
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();
}
예제 #11
0
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));
			}
		}
		
	}
	
}
예제 #12
0
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;
	}
}
예제 #13
0
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);
	}
};
예제 #14
0
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);
			}
		}
예제 #15
0
/// \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 );
	}
}
예제 #16
0
  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;
  }