The library has both a C and C++ API, which map 100% 1:1 in features.

C++ API

The C++ API is part of the UXDGBaseDir.hpp header. It looks like this:

namespace UXDG
{
    std::string XDG_DATA_HOME() noexcept;
    std::string XDG_CONFIG_HOME() noexcept;
    std::string XDG_STATE_HOME() noexcept;
    std::string XDG_CACHE_HOME() noexcept;
    std::string XDG_BIN_PATH_HOME() noexcept;

    UVK_PUBLIC_API std::string XDG_RUNTIME_DIR() noexcept;

    UVK_PUBLIC_API std::string HOME() noexcept;

    std::vector<std::string> XDG_DATA_DIRS() noexcept;
    std::vector<std::string> XDG_CONFIG_DIRS() noexcept;

    std::string getEnv(const char* name, const char* val) noexcept;
    std::vector<std::string> splitEnv(const std::string& str) noexcept;

    void setStickyBit(const std::string& location) noexcept;

    std::string XDG_DESKTOP_DIR() noexcept;
    std::string XDG_DOWNLOAD_DIR() noexcept;
    std::string XDG_TEMPLATES_DIR() noexcept;
    std::string XDG_PUBLICSHARE_DIR() noexcept;
    std::string XDG_DOCUMENTS_DIR() noexcept;
    std::string XDG_MUSIC_DIR() noexcept;
    std::string XDG_PICTURES_DIR() noexcept;
    std::string XDG_VIDEOS_DIR() noexcept;

    std::string getXDGUserDir(const char* dir, UXDG_XDG_USER_DIR_STANDARD_TYPE type = XDG_USER_DIR_STANDARD_TYPE_CUSTOM) noexcept;
}

In source code, all functions are annotated with their respective extracts from the XDG Basedir specification.

XDG_DATA_HOME

XDG Basedir spec: $XDG_DATA_HOME defines the base directory relative to which user-specific data files should be stored. If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be

XDG_CONFIG_HOME

XDG Basedir spec: $XDG_CONFIG_HOME defines the base directory relative to which user-specific configuration files should be stored. If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME/.config should be used.

XDG_STATE_HOME

XDG Basedir spec: The $XDG_STATE_HOME contains state data that should persist between (application) restarts, but that is not important or portable enough to the user that it should be stored in $XDG_DATA_HOME. It may contain:

XDG_CACHE_HOME

XDG Basedir spec: $XDG_CACHE_HOME defines the base directory relative to which user-specific non-essential data files should be stored. If $XDG_CACHE_HOME is either not set or empty, a default equal to $HOME/.cache should be used.

XDG_RUNTIME_DIR

XDG Basedir spec: $XDG_RUNTIME_DIR defines the base directory relative to which user-specific non-essential runtime files and other file objects (such as sockets, named pipes, ...) should be stored. The directory MUST be owned by the user, and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700.

The lifetime of the directory MUST be bound to the user being logged in. It MUST be created when the user first logs in and if the user fully logs out the directory MUST be removed. If the user logs in more than once he should get pointed to the same directory, and it is mandatory that the directory continues to exist from his first login to his last logout on the system, and not removed in between. Files in the directory MUST not survive reboot or a full logout/login cycle.

The directory MUST be on a local file system and not shared with any other system. The directory MUST be fully-featured by the standards of the operating system. More specifically, on Unix-like operating systems AF_UNIX sockets, symbolic links, hard links, proper permissions, file locking, sparse files, memory mapping, file change notifications, a reliable hard link count must be supported, and no restrictions on the file name character set should be imposed. Files in this directory MAY be subjected to periodic clean-up. To ensure that your files are not removed, they should have their access time timestamp modified at least once every 6 hours of monotonic time or the 'sticky' bit should be set on the file.

If $XDG_RUNTIME_DIR is not set applications should fall back to a replacement directory with similar capabilities and print a warning message. Applications should use this directory for communication and synchronization purposes and should not place larger files in it, since it might reside in runtime memory and cannot necessarily be swapped out to disk.

HOME

Returns the absolute path to the home directory of the user running the application.

XDG_BIN_PATH_HOME

XDG Basedir spec: User-specific executable files may be stored in $HOME/.local/bin. Distributions should ensure this directory shows up in the UNIX $PATH environment variable, at an appropriate place.

Since $HOME might be shared between systems of different architectures, installing compiled binaries to $HOME/.local/bin could cause problems when used on systems of differing architectures. This is often not a problem, but the fact that $HOME becomes partially architecture-specific if compiled binaries are placed in it should be kept in mind.

XDG_DATA_DIRS

XDG Basedir spec: $XDG_DATA_DIRS defines the preference-ordered set of base directories to search for data files in addition to the $XDG_DATA_HOME base directory. The directories in $XDG_DATA_DIRS should be separated with a colon ':'.

If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used.

The order of base directories denotes their importance; the first directory listed is the most important.

XDG_CONFIG_DIRS

XDG Basedir spec: $XDG_CONFIG_DIRS defines the preference-ordered set of base directories to search for configuration files in addition to the $XDG_CONFIG_HOME base directory. The directories in $XDG_CONFIG_DIRS should be separated with a colon ':'.

If $XDG_CONFIG_DIRS is either not set or empty, a value equal to /etc/xdg should be used.

The order of base directories denotes their importance; the first directory listed is the most important.

getEnv

Given 2 string arguments, the name of an environment variable and a default string, returns the value of the environment variable or the default string if the variable does not exist.

splitEnv

Given a string argument, splits the string and returns an array of strings, split from the original string. The string is formatted in environment variable list format like this: a:b:c:d:e:f.

setStickyBit

Given a path to a file or directory, sets the sticky bit of it. This is useful for files or directories in XDG_RUNTIME_DIR that you don't want to be automatically cleaned up.

XDG Basedir spec: ...Files in this directory MAY be subjected to periodic clean-up. To ensure that your files are not removed, they should have their access time timestamp modified at least once every 6 hours of monotonic time or the 'sticky' bit should be set on the file.

XDG User directories

While not documented anywhere, the so called "XDG User dirs" are used by most distributions. They are defined in the following file: $XDG_CONFIG_HOME/user-dirs.dirs and are used by many desktops and applications to provide convenient folders for pictures, videos, downloads, etc. Here is a normal user-dirs.dirs file:

XDG_DESKTOP_DIR="$HOME/Desktop"
XDG_DOWNLOAD_DIR="$HOME/Downloads"
XDG_TEMPLATES_DIR="$HOME/Templates"
XDG_PUBLICSHARE_DIR="$HOME/Public"
XDG_DOCUMENTS_DIR="$HOME/Documents"
XDG_MUSIC_DIR="$HOME/Music"
XDG_PICTURES_DIR="$HOME/Pictures"
XDG_VIDEOS_DIR="$HOME/Videos"

Fortunately, we have added functions for fetching these directories, and they correspond directly to their names. Please note that the file is read only once: once one of these functions is called. This should not be an issue in most cases, but may complicate things a bit for applications that want to both create and consume the directories.

Non-standard user directories

While these directories above are "standard"(refers to general desktop environment usage, since they are not standardised in any way), other directory variables can also be added to the file.

To fetch them, use the getXDGUserDir function. The first argument is the name of the variable, the second is an enum of type UXDG_XDG_USER_DIR_STANDARD_TYPE which defaults to XDG_USER_DIR_STANDARD_TYPE_CUSTOM. If not set to XDG_USER_DIR_STANDARD_TYPE_CUSTOM it will simply try to fetch standard types, except when the value is larger or equal to XDG_USER_DIR_STANDARD_TYPE_SIZE, in which case it will default to custom variable behaviour.

C API

The C API is the same, except that all functions are prefixed with UXDG_ to compensate for namespaces not existing. Additionally, instead of std::string or std::vector<std::string>, functions return char* and char** respectively. The return value of functions that return char* should be deallocated using UXDG_FreeResult_Str. For char**, UXDG_FreeResult_Arr.

All functions that return arrays also take a size_t* whose value will be set to the size of the array.

Error handling

Most functions don't report errors, as they have fallback defaults. The following ones do not have defaults and should be checked if they exist.

XDG_RUNTIME_DIR

XDG_RUNTIME_DIR returns an empty string if the XDG_RUNTIME_DIR environment variable is not set. This is because the standard does not specify a default for it.

XDG_DATA_DIRS, XDG_CONFIG_DIRS, splitEnv

In the C++ API, the arrays may be empty if the given string or environment variable is empty.

In the C API, the following functions return char**. This pointer may be equal to nullptr if the environment variables are empty. Check against it for maximum safety when using the C API.

String functions

If a function returns a string, the string may be empty if the environment variable is empty. In the C API, this is represented by a nullptr.