diff options
| author | Joel Klinghed <the_jk@opera.com> | 2015-07-13 13:04:24 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@opera.com> | 2015-07-13 13:04:24 +0200 |
| commit | 1d8af5a018282dc6a93b9ed7c87d9d2f87287b14 (patch) | |
| tree | c47c19f7c27fd1774d1455b088eb207c611d30ed /src/paths.h | |
| parent | 59709e4cb30f2ff8666522d5b758731ab618adbc (diff) | |
Copy the dependencies from sawmill project
Diffstat (limited to 'src/paths.h')
| -rw-r--r-- | src/paths.h | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/src/paths.h b/src/paths.h new file mode 100644 index 0000000..8be56f8 --- /dev/null +++ b/src/paths.h @@ -0,0 +1,261 @@ +/** + * \file paths.h + * XDG Directory Specification implementation + */ + +#ifndef PATHS_H +#define PATHS_H + +/** + * Opaque type for paths + */ +typedef struct paths_t paths_t; + +/** + * Opaque type for a currently open file + */ +typedef struct paths_file_t paths_file_t; + +/** + * The different sources or directories if you will that are in the + * specification. + */ +typedef enum paths_source_t +{ + /** directory for data files */ + PATHS_DATA, + /** directory for config files */ + PATHS_CONFIG, + /** directory for cache files */ + PATHS_CACHE, + /** directory for runtime files */ + PATHS_RUNTIME, +} paths_source_t; + +/** Do not block write calls */ +#define PATHS_NONBLOCK (0x01) +/** Append on each write */ +#define PATHS_APPEND (0x02) +/** Create file if needed */ +#define PATHS_CREATE (0x04) +/** Truncate file when opening */ +#define PATHS_TRUNCATE (0x08) +/** If PATHS_CREATE is set, give error if file already exists */ +#define PATHS_EXCLUSIVE (0x10) + +/** + * Create a new paths. + * Initializes the list of directories from enviroment variables. + * Returned object has a reference count of one. + * Threadsafe. + * Returns NULL in case of allocation errors. + * @return a new paths + */ +MALLOC paths_t* paths_new(void); + +/** + * Increase the reference count for paths. + * Threadsafe. + * @param paths paths object, may not be NULL + */ +NONULL void paths_ref(paths_t* paths); + +/** + * Decrease the reference count for paths and free if it reached zero. + * Threadsafe. + * @param paths paths object, may be NULL + */ +void paths_unref(paths_t* paths); + +/** + * Get single directory where user-specific files should be written. + * May only return NULL for PATHS_RUNTIME all other sources are guaranteed to + * return a non-NULL string. They may however return non-existant paths. + * PATHS_RUNTIME will return NULL if no such path was found as it has no + * default. + * If you wish paths to be created if missing, please use paths_write(). + * Threadsafe. + * @param paths paths object, may not be NULL + * @param source requested directory + * @return absolute path to directory or NULL + */ +NONULL const char* paths_user_dir(paths_t* paths, paths_source_t source); + +/** + * Get preference ordered list of directories to search for files. + * All paths are absolute and NULL terminated. The list itself is NULL + * terminated and may never be empty. Path returned by paths_user_dir() for + * the same source is not included. + * Will return NULL for PATHS_CACHE and PATHS_RUNTIME as they are only + * user-specific writable directories. + * Threadsafe. + * @param paths paths object, may not be NULL + * @param source requested directory + * @return NULL terminated list of absolute paths to search or NULL + */ +NONULL const char** paths_search_dirs(paths_t* paths, paths_source_t source); + +/** + * Callback called with the result(s) from paths_find(). May be called from + * any thread. Return false to cancel the search, true to continue until all + * has been found. filename will be NULL when no more matches was found. + * The filename pointer is only valid until the callback has returned. + * @param userdata userdata given to paths_find() + * @param filenamme found file or NULL if no more results + * @return true to continue the search, false to not */ +typedef bool (* paths_find_callback_t)(void* userdata, const char* filename); + +/** + * Asynchronous search for matching files in directories for source. + * Returned in preference order, first paths_user_dir() and then + * paths_search_dirs(). + * The callback is always called at least once. + * Match may use *, ?, [] and {} glob matches. It may also contain / characters + * to search in subdirectories + * Threadsafe. + * @param paths paths object, may not be NULL + * @param source requested directory + * @param match glob pattern to search with. may not be NULL + * @param find_callback callback to call when finding results, may not be NULL + * @param userdata argument to callback, may be NULL + */ +NONULL_ARGS(1, 3, 4) +void paths_find(paths_t* paths, paths_source_t source, const char* match, + paths_find_callback_t find_callback, void* userdata); + +/** + * Synchronous setup to create file in directory. + * Returns NULL in case of error, see errno for details. + * Depending on source and convention, the actual file may not be created with + * the given name until paths_file_close(). + * The file will eventually always end up in paths_user_dir() for directory. + * If any part of the target path is missing it will be created if possible. + * If flags contains PATHS_CREATE then the 5th argument mode_t mode must be + * given, just as for open(). + * Threadsafe but what happens if two threads at the same time opens the same + * target file is up to the platforms locking mechanism. + * The returned paths_file_t is not threadsafe. + * @param paths paths object, may not be NULL + * @param source target directoru + * @param filename relative path of target file, may not be NULL + * @param flags flags + * @param ... mode if PATHS_CREATE is included in flags + * @return a file reference or NULL + */ +NONULL paths_file_t* paths_write(paths_t* paths, paths_source_t source, + const char* filename, unsigned int flags, + ...); + +/** + * Write data to file. + * Works just as libc write(). + * Not threadsafe, + * the paths_file_t must only be accessed by one thread at a time. + * @param file target file, may not be NULL + * @param data data to write, may be NULL if size is zero + * @param size the maximum number of bytes to read from data + * @return number of bytes written to target + */ +NONULL_ARGS(1) +ssize_t paths_file_write(paths_file_t* file, const void* data, size_t size); + +/** + * Close and finish saving file. + * If the file was saved successfully, the paths_file_t object is freed. + * If the save failed in any way, the object is not freed so you must call + * paths_file_abort() to finish up (or call paths_file_close() again and + * hope for better luck this time). + * Not threadsafe, + * the paths_file_t must only be accessed by one thread at a time. + * @param file target file, may not be NULL + * @return zero on success, non-zero in case of error + */ +NONULL int paths_file_close(paths_file_t* file); + +/** + * Abort saving the file. The target file is removed unless the original version + * before paths_write() could be restored. + * Not threadsafe, + * the paths_file_t must only be accessed by one thread at a time. + * @param file target file, may be NULL + */ +void paths_file_abort(paths_file_t* file); + +/** + * Get absolute path to directory where user-specific data files should be + * written. Returned directory may not exist. + * Threadsafe. + * @param paths paths object, may not be NULL + * @return absolute path to data directory + */ +static inline NONULL const char* paths_user_data(paths_t* paths) +{ + return paths_user_dir(paths, PATHS_DATA); +} + +/** + * Get absolute path to directory where user-specific config files should be + * written. Returned directory may not exist. + * Threadsafe. + * @param paths paths object, may not be NULL + * @return absolute path to config directory + */ +static inline NONULL const char* paths_user_config(paths_t* paths) +{ + return paths_user_dir(paths, PATHS_CONFIG); +} + +/** + * Get absolute path to directory where user-specific cache files should be + * written. Returned directory may not exist. + * Threadsafe. + * @param paths paths object, may not be NULL + * @return absolute path to cache directory + */ +static inline NONULL const char* paths_user_cache(paths_t* paths) +{ + return paths_user_dir(paths, PATHS_CACHE); +} + +/** + * Get absolute path to directory where user-specific runtime files should be + * written. + * If not defined in enviroment or not valid NULL is returned. + * Threadsafe. + * @param paths paths object, may not be NULL + * @return absolute path to runtime directory or NULL + */ +static inline NONULL const char* paths_user_runtime(paths_t* paths) +{ + return paths_user_dir(paths, PATHS_RUNTIME); +} + +/** + * Get preference ordered list of directories to search for data files. + * All paths are absolute and NULL terminated. The list itself is NULL + * terminated and may never be empty. Path returned by paths_user_data() + * is not included. + * Threadsafe. + * @param paths paths object, may not be NULL + * @return NULL terminated list of absolute paths to search + */ +static inline NONULL const char** paths_data(paths_t* paths) +{ + return paths_search_dirs(paths, PATHS_DATA); +} + +/** + * Get preference ordered list of directories to search for config files. + * All paths are absolute and NULL terminated. The list itself is NULL + * terminated and may never be empty. Path returned by paths_user_config() + * is not included. + * Threadsafe. + * @param paths paths object, may not be NULL + * @return NULL terminated list of absolute paths to search + */ +static inline NONULL const char** paths_config(paths_t* paths) +{ + return paths_search_dirs(paths, PATHS_CONFIG); +} + +#endif /* PATHS_H */ |
