commit f812f15ed38194cfb86416e9770581b76343cbbf Author: tastytea Date: Fri Aug 10 03:28:31 2018 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..60368fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/build/ +/doc/ +/update_doc.sh diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1a8f5f7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required (VERSION 3.7) +project(xdgjson + VERSION 0.1.0 + LANGUAGES CXX +) + +include(GNUInstallDirs) +find_package(PkgConfig REQUIRED) +pkg_check_modules(LIBXDG_BASEDIR REQUIRED libxdg-basedir) +pkg_check_modules(JSONCPP REQUIRED jsoncpp) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") + +include_directories(${LIBXDG_BASEDIR_INCLUDE_DIRS}) +include_directories(${JSONCPP_INCLUDE_DIRS}) + +link_directories(${LIBXDG_BASEDIR_LIBRARY_DIRS}) +link_directories(${JSONCPP_LIBRARY_DIRS}) + +add_library(xdgjson SHARED src/xdgjson.cpp) +set_target_properties(xdgjson PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${xdgjson_VERSION_MAJOR}) +target_link_libraries(xdgjson + ${LIBXDG_BASEDIR_LIBRARIES} ${JSONCPP_LIBRARIES} + stdc++fs) + +add_library(xdgjson_static STATIC src/xdgjson.cpp) +set_target_properties(xdgjson_static PROPERTIES + OUTPUT_NAME xdgjson) + +add_executable(example src/example.cpp) +target_link_libraries(example xdgjson ${JSONCPP_LIBRARIES}) + +install(TARGETS xdgjson LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(TARGETS xdgjson_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(FILES src/xdgjson.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..6bb5974 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,198 @@ +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "xdgjson" +PROJECT_NUMBER = 0.0.0 +INPUT = README.md src/ +USE_MDFILE_AS_MAINPAGE = README.md +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = YES +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO +SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +INPUT_ENCODING = UTF-8 +RECURSIVE = NO +EXCLUDE_SYMLINKS = NO +EXAMPLE_PATH = src +EXAMPLE_RECURSIVE = YES +FILTER_SOURCE_FILES = NO +SOURCE_BROWSER = NO +INLINE_SOURCES = YES +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +CLANG_ASSISTED_PARSING = NO +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +GENERATE_HTML = YES +HTML_OUTPUT = doc/html +HTML_FILE_EXTENSION = .html +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = NO +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +SEARCHENGINE = NO +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHDATA_FILE = searchdata.xml +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_SOURCE_CODE = NO +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_SUBDIR = +MAN_LINKS = NO +GENERATE_XML = NO +XML_OUTPUT = xml +XML_PROGRAMLISTING = YES +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +DOCBOOK_PROGRAMLISTING = NO +GENERATE_AUTOGEN_DEF = NO +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +SKIP_FUNCTION_MACROS = YES +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +PERL_PATH = /usr/bin/perl +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/README.md b/README.md new file mode 100644 index 0000000..712a436 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +**xdgjson** is a very simple wrapper around jsoncpp written in C++. It reads +and writes files in `${XDG_CONFIG_HOME}`. It creates subdirectories if +necessary. + +### Dependencies + +* C++ compiler +* [cmake](https://cmake.org/) +* [pkgconfig](https://pkgconfig.freedesktop.org/wiki/) +* [jsoncpp](https://github.com/open-source-parsers/jsoncpp) +* [libxdg-basedir](http://repo.or.cz/w/libxdg-basedir.git) + +### Usage + +You can create dynamic and static libraries: + +```SH +mkdir build +cd build +cmake .. +make +make install +``` + +Or just copy `xdgjson.hpp` and `xdgjson.cpp` into your project folder. + +### Documentation + +`xdgjson.hpp` has explanatory comments in it and there is an +[example](src/example.cpp). The reference is also available at +[doc.schlomp.space/xdgjson/](https://doc.schlomp.space/xdgjson/classxdgjson.html). diff --git a/generate_doc.sh b/generate_doc.sh new file mode 100755 index 0000000..580bd7c --- /dev/null +++ b/generate_doc.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ -f Doxyfile ]; then + mkdir -p doc + (cat Doxyfile && echo -n "PROJECT_NUMBER = " && + grep -Eo '[0-9]+.[0-9]+.[0-9]+$' CMakeLists.txt) \ + | doxygen - +fi diff --git a/src/example.cpp b/src/example.cpp new file mode 100644 index 0000000..b8e8aeb --- /dev/null +++ b/src/example.cpp @@ -0,0 +1,13 @@ +#include +#include +#include "xdgjson.hpp" + +int main(int argc, char *argv[]) +{ + xdgjson config("test.json", "xdgjson"); + config.read(); + Json::Value &json = config.get_json(); + std::cout << "Hello: " << json["Hello"].asString() << '\n'; + json["Hello"] = "World"; + config.write(); +} diff --git a/src/xdgjson.cpp b/src/xdgjson.cpp new file mode 100644 index 0000000..5c5782f --- /dev/null +++ b/src/xdgjson.cpp @@ -0,0 +1,83 @@ +/* Public Domain / CC-0 + * Author: tastytea + */ + +#if __cplusplus >= 201703L + #include +#else + #include +#endif +#include +#include +#include +#include "xdgjson.hpp" + +#if __cplusplus >= 201703L + namespace fs = std::filesystem; +#else + namespace fs = std::experimental::filesystem; +#endif + +xdgjson::xdgjson(const string &filename, const string &subdir) +: _json() +{ + xdgHandle xdg; + xdgInitHandle(&xdg); + _filepath = xdgConfigHome(&xdg); + xdgWipeHandle(&xdg); + + if (!subdir.empty()) + { + _filepath += '/' + subdir; + if (!fs::exists(_filepath)) + { + fs::create_directory(_filepath); + } + } + _filepath += '/' + filename; +} + +const bool xdgjson::read() +{ + std::ifstream file(_filepath); + if (file.is_open()) + { + std::stringstream config; + config << file.rdbuf(); + file.close(); + config >> _json; + + return true; + } + else + { + return false; + } +} + +const bool xdgjson::write() +{ + std::ofstream file(_filepath); + if (file.is_open()) + { + const string config = _json.toStyledString(); + file.write(config.c_str(), config.length()); + file.close(); + + return true; + } + else + { + return false; + } +} + +Json::Value &xdgjson::get_json() +{ + return _json; +} + +const string xdgjson::get_filepath() const +{ + return _filepath; +} diff --git a/src/xdgjson.hpp b/src/xdgjson.hpp new file mode 100644 index 0000000..11b58c4 --- /dev/null +++ b/src/xdgjson.hpp @@ -0,0 +1,74 @@ +/* Public Domain / CC-0 + * Author: tastytea + */ + +#ifndef XDGJSON_HPP +#define XDGJSON_HPP + +#include +#include + +using std::string; + +class xdgjson +{ +public: + /*! + * @brief Checks if subdir is present, creates it if necessary + * + * Example: + * @code + * xdgjson config("test.json", "subdirectory"); + * @endcode + * + * @param filename The name of the file, including extension + * @param subdir The subdir (optional) + */ + explicit xdgjson(const string &filename, const string &subdir = ""); + + /*! + * @brief Read the file + * + * @return `true` on success + */ + const bool read(); + + /*! + * @brief Write the file + * + * @return `true` on success + */ + const bool write(); + + /*! + * @brief Returns a reference to the config as Json::Value + * + * Example: + * @code + * Json::Value &json = config.get_json(); + * @endcode + */ + Json::Value &get_json(); + + /*! + * @brief Returns the complete filepath + */ + const string get_filepath() const; + +private: + /*! + * Holds the contents of the JSON file + */ + Json::Value _json; + + /*! + * Complete filepath + */ + string _filepath; +}; + +/*! + * @example example.cpp + */ + +#endif // XDGJSON_HPP