aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorkatherine <ageha@airen-no-jikken.icu>2019-12-07 15:16:24 -0700
committerkatherine <ageha@airen-no-jikken.icu>2019-12-07 15:16:24 -0700
commit12476abdab83f765da8173e73b172ecf4749f6b9 (patch)
tree819cd77d204f4c9e793364e421b5c225ce9026c4 /README.md
downloadsimple-xdg-bdirs-12476abdab83f765da8173e73b172ecf4749f6b9.tar.gz
initial commit
Diffstat (limited to 'README.md')
-rw-r--r--README.md199
1 files changed, 199 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4173770
--- /dev/null
+++ b/README.md
@@ -0,0 +1,199 @@
+simple-xdg-bdirs
+================
+
+[simple-xdg-bdirs.h](simple-xdg-bdirs.h) is a single header file which
+implements calculating file paths according to the
+[XDG Base Directory Specification][1].
+
+brief summary
+-------------
+
+the XDG Base Directory Specification is a popular specification which defines
+predictable locations for programs to store their config, runtime, cache, and
+data files. these locations are calculated based on specially named environment
+variables, with certain directories defined as default fallbacks.
+
+this single-header library provides a couple of simple functions to calculate
+those locations at runtime, as well as functions to build file paths against
+them.
+
+example
+-------
+
+the following example file is available as [example.c](doc/example.c), which
+you can compile and play with yourself.
+
+```C
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "../simple-xdg-bdirs.h"
+
+/* a simple example which attempts to read a value from a configuration file
+ * and write it back to a cache file */
+int main(int argc, char *argv[])
+{
+ char *s, *wdir, **rdirs, **cur;
+
+ /* alloc a null-terminated array of directories in which to search for
+ * configuration files */
+ rdirs = simple_xdg_bdirs_read_dirs(SIMPLE_XDG_BDIRS_CONFIG);
+
+ /* in case of error, errno is set, so perror works */
+ if (rdirs == NULL) {
+ perror(NULL);
+ return 1;
+ }
+
+ /* search in the config directories for the given relative path. if not
+ * found in the first, the second will be checked as a fallback etc */
+ s = simple_xdg_bdirs_fullpath_read("xdg_bdirs_test/config.conf", rdirs);
+
+ /* element strings of rdirs must also be freed */
+ for (cur = rdirs; *cur != NULL; cur++)
+ free(*cur);
+ free(rdirs);
+
+ /* check for errors again */
+ if (s == NULL) {
+ perror(NULL);
+ return 1;
+ }
+
+ /* print the fullpath of the file that was found */
+ puts(s);
+ free(s);
+
+ /* locate the directory into which runtime files should be written
+ * (things like sockets or lock files) */
+ wdir = simple_xdg_bdirs_write_dir(SIMPLE_XDG_BDIRS_RUNTIME);
+
+ if (wdir == NULL) {
+ perror(NULL);
+ return 1;
+ }
+
+ /* a convenience function that builds a fullpath from a relative path and
+ * write directory */
+ s = simple_xdg_bdirs_fullpath_write("xdg_bdirs_test.lock", wdir);
+
+ free(wdir);
+
+ if (s == NULL) {
+ perror(NULL);
+ return 1;
+ }
+
+ puts(s);
+ free(s);
+
+ return 0;
+}
+```
+
+basically, each function returns either a string or `NULL`, in which case
+`errno` will also be set. simple!
+
+interface
+---------
+
+```C
+enum simple_xdg_bdirs_ftype {
+ SIMPLE_XDG_BDIRS_DATA,
+ SIMPLE_XDG_BDIRS_CONFIG,
+ SIMPLE_XDG_BDIRS_CACHE,
+ SIMPLE_XDG_BDIRS_RUNTIME,
+};
+```
+
+one of these types is passed to each of the functions below, denoting the
+category of file to which the functions actions ought to correspond.
+
+- `SIMPLE_XDG_BDIRS_DATA` is used for persistent data created by a program
+- `SIMPLE_XDG_BDIRS_CONFIG` is used for a program's configuration files
+- `SIMPLE_XDG_BDIRS_CACHE` is used for transient data which may be deleted
+ without warning by the system
+- `SIMPLE_XDG_BDIRS_RUNTIME` is used for "runtime files", such as lock files
+ or sockets
+
+
+```C
+static char*
+simple_xdg_bdirs_write_dir(enum simple_xdg_bdirs_ftype type)
+```
+
+this function finds and returns a single string that is the path of a
+directory into which all files of type `type` ought to be written.
+
+because the location of this directory is determined at runtime, and in
+particular because it relies on the state of the filesystem and environment
+variables, it is possible that no good candidate directory will be found, in
+which case `NULL` will be returned.
+
+if a string is returned, it is guaranteed to always have a trailing '/',
+meaning that a relative path can be appended directly without fear of
+unintended results, like '/etx/xdgherbstluftwm'
+
+errors:
+- `ENOENT`: no candidate dir found
+- `EINVAL`: bad argument
+- `EOVERFLOW`: extremely-large string encountered (unlikely)
+- `ENOMEM`: malloc err
+
+
+```C
+static char**
+simple_xdg_bdirs_read_dirs(enum simple_xdg_bdirs_ftype type)
+```
+
+this function finds and returns a null-terminated array of strings that are
+the paths, in order, where one ought to search for files of type `type` when
+reading.
+
+because some filetypes have only a single, environment-determined read dir,
+it's possible that none will be found, in which case `NULL` will be
+returned.
+
+returned strings are guaranteed to always have a trailing '/', meaning that
+a relative path can be appended directly without fear of unintended results,
+like '/etx/xdgherbstluftwm'
+
+errors:
+- `ENOENT`: no candidate dirs found
+- `EINVAL`: bad argument
+- `EOVERFLOW`: extremely-large string encountered (unlikely)
+- `ENOMEM`: malloc err
+
+
+```C
+static char*
+simple_xdg_bdirs_fullpath_read(const char *rel_path, char **read_dirs)
+```
+
+take a relative path and set of directories returned from
+`simple_xdg_bdirs_read_dirs` and return either a full path to an existing
+file or, on error, NULL
+
+errors
+- `ENOENT`: target file not found or readable
+- `EINVAL`: bad argument
+- `EOVERFLOW`: extremely-large string encountered (unlikely)
+- `ENOMEM`: malloc err
+
+
+```C
+static char*
+simple_xdg_bdirs_fullpath_write(const char *rel_path, char *write_dir)
+```
+
+take a relative path and a write directory returned from
+`simple_xdg_bdirs_write_dir` and return either a full path to the targeted
+write path or, on error, NULL
+
+errors
+- `ENOENT`: write_dir is not found or not write accessible
+- `EINVAL`: bad argument
+- `EOVERFLOW`: extremely-large string encountered (unlikely)
+- `ENOMEM`: malloc err
+
+[1]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html