Files
klammertext/mac/file.h
T

126 lines
6.6 KiB
C++
Raw Normal View History

#pragma once
#include <string>
#include <vector>
#include <filesystem>
#include <functional>
namespace fs = std::filesystem;
std::string file_basename(const std::string& filename);
std::string extension(const std::string& filename);
std::string file_directory(const std::string& filename);
std::string absolute_pathname(const std::string& filename, const std::string& base="");
std::string relative_pathname(const std::string& filename);
std::string relative_pathname(const std::string& filename, const std::string& base);
fs::path relative_to_cwd(const fs::path& input);
// The separator of a directory list in an environment variable
// (KLAMMERTEXT_FONTS, KLAMMERTEXT_KLAMMERSETS): ';' on Windows, where a drive
// letter puts a colon inside every absolute path, ':' everywhere else -- the
// convention of PATH on each system.
#ifdef _WIN32
constexpr char path_list_separator = ';';
#else
constexpr char path_list_separator = ':';
#endif
// The suffix of a shared library loaded at run time (the library a
// "@eval :cpp" names): ".dll" on Windows, ".so" everywhere else -- the same
// choice makefile.env's DSO makes when it builds one.
#ifdef _WIN32
constexpr const char* shared_library_suffix = ".dll";
#else
constexpr const char* shared_library_suffix = ".so";
#endif
// The user's home directory as the system names it: HOME; on Windows
// USERPROFILE first, so the directory is the same from PowerShell (no HOME)
// and from an MSYS2 shell (which may set HOME to its own /home/<user>).
std::string home_directory();
// The first PROGRAM on PATH (split on path_list_separator; on Windows the
// name also tried with ".exe"), or "" when none: what "which" answers, without
// spawning a shell -- on Windows popen()'s cmd.exe has no "which".
std::string find_in_path(const std::string& program);
// The directories listed in an environment variable, split on
// path_list_separator, empty entries dropped; DEFAULT_SUBDIR under the home
// directory when the variable is unset or empty.
std::vector<std::string> directory_list(const char* variable, const std::string& default_subdir);
bool file_exists(const std::string& pathname, bool error_if_not=false, bool is_directory=false);
// Text to its lines, and a file to (its whole text, its lines). These
// moved here from katom.{h,cpp} on 2026-09-02: neither produces a katom,
// and the second OPENS A FILE, so by the test in katomize.h -- does a
// character stream enter? -- they were in the wrong place. They are read
// almost exclusively as katomize_lines(line_split(text), source), which is
// what kept them next to katomization for so long; adjacency at the call
// site is not membership.
std::vector<std::string> line_split(const std::string& s);
std::pair<std::string, std::vector<std::string>> line_split(const fs::path& pathname);
// Filenames may contain spaces. A filename LIST in a flat string or an
// argument vector is separated by a standalone "/" token (whitespace on both
// sides; never a legal input filename -- "/" alone is the root directory).
// Without a separator, whitespace-split tokens that do not name existing
// files are greedily rejoined with their neighbors into names that do (the
// rescue is announced). A leading "~/" (or bare "~") expands to $HOME.
std::string expand_tilde(const std::string& path);
std::vector<std::string> group_filename_tokens(
const std::vector<std::string>& tokens, const std::string& base_dir="");
std::vector<std::string> resolve_filename_list(
const std::string& text, const std::string& base_dir="");
std::string string_from_file(const std::string& pathname, bool strip_surrounding_whitespace=false);
// A Klammertext source (a .kt, a .k, a @read file): string_from_file() plus
// the check that it IS text Klammertext can read -- a File_error names the
// first byte that is not UTF-8 (line and character), or a UTF-16 file by its
// byte-order mark, with what to do in an editor. string_from_file() itself
// stays permissive: it also reads XeTeX logs and a shell command's stderr.
std::string klammertext_from_file(const std::string& pathname);
void string_to_file(const std::string& pathname, std::string contents);
std::vector<std::string> get_files_in_directory(const std::string& dir);
std::string find_file(const std::string& basename, std::vector<std::string> search_path,
bool error_if_not_found=true);
std::vector<fs::path>
find_file_recursive(const fs::path& root, const std::string& filename,
bool only_one=true); //, Locator loc=Locator());
std::vector<fs::path>
find_file_from_roots(const std::vector<std::string>& roots, const std::string& filename, bool only_one);
fs::path klammertext_filename(
const std::string& basename, bool error_if_missing=true, bool make_directory_if_missing=false);
std::vector<std::string> sks_dirs();
std::vector<std::string> get_sks_directories(const std::string& s, bool include_argument=true);
std::string symbolic_klammertext_filename(std::string filename);
std::string cache_directory(const std::string& subdirectory, std::string parent_directory="");
std::time_t to_time_t(const fs::file_time_type& ftime);
bool in_modification_order(std::string filename1, std::string filename2);
void write_to_cache(const std::string& cache_dir, const std::string& basename, const std::string& text);
std::string read_from_cache(const std::string& cache_dir, const std::string& basename);
bool cache_requires_update(const std::string& cache_dir, const std::string& file_to_cache, const std::string& basename);
std::vector<fs::path> pathnames_with_extension(
const fs::path& dir, const std::string extension
);
//std::string find_file(const fs::path& root, const std::string& name);
std::vector<std::string> find_files_with_extension(
const fs::path& root, const std::string& ext, bool case_insensitive=false);
std::string combine_files(
const std::vector<std::string>& filenames,
const std::string& prolog="", const std::string& epilog="",
const std::function <std::string(std::string)>& processor = nullptr);
bool files_differ(const fs::path& p1,
const fs::path& p2,
std::size_t buffer_size = 1 << 16); // 64 KiB
// Copy a single file with an explicit binary stream (NOT std::filesystem
// copy_file/copy), forcing the destination world-readable. Required for output
// onto Apple `container` virtiofs mounts — see the definition in file.cpp.
void copy_file_stream(const fs::path& src, const fs::path& dst);
void copy_preserving_basename(
const std::vector<std::string>& filenames, const std::string& output_directory,
const std::string& link_directory);
fs::path resolve_relative_to(const fs::path& relative, const fs::path& base=std::filesystem::current_path());