Verified Commit 60cbfe9e authored by Alberto Miranda's avatar Alberto Miranda ♨️
Browse files

Add source files

parent 0bac899a
Loading
Loading
Loading
Loading

CMakeLists.txt

0 → 100644
+121 −0
Original line number Diff line number Diff line
################################################################################
# Copyright 2017-2022, Barcelona Supercomputing Center (BSC), Spain            #
#                                                                              #
# This software was partially supported by the EuroHPC-funded project ADMIRE   #
#   (Project ID: 956748, https://www.admire-eurohpc.eu).                       #
#                                                                              #
# This file is part of file_options.                                           #
#                                                                              #
# file_options is free software: you can redistribute it and/or modify         #
# it under the terms of the GNU General Public License as published by         #
# the Free Software Foundation, either version 3 of the License, or            #
# (at your option) any later version.                                          #
#                                                                              #
# file_options is distributed in the hope that it will be useful,              #
# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
# GNU General Public License for more details.                                 #
#                                                                              #
# You should have received a copy of the GNU General Public License            #
# along with file_options.  If not, see <https://www.gnu.org/licenses/>.       #
#                                                                              #
# SPDX-License-Identifier: GPL-3.0-or-later                                    #
################################################################################

# ##############################################################################
# Define the CMake project and configure CMake
# ##############################################################################

cmake_minimum_required(VERSION 3.14)

project(
        file_options
        VERSION 0.1.0
        LANGUAGES CXX
)

# Set default build type and also populate a list of available options
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)

if (NOT is_multi_config)
    set(default_build_type "Release")
    set(allowed_build_types Debug Release MinSizeRel RelWithDebInfo)

    set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${allowed_build_types}")

    if (NOT CMAKE_BUILD_TYPE)
        set(CMAKE_BUILD_TYPE
                "${default_build_type}"
                CACHE STRING "Choose the type of build." FORCE
                )
    elseif (NOT CMAKE_BUILD_TYPE IN_LIST allowed_build_types)
        message(FATAL_ERROR "Unknown build type: ${CMAKE_BUILD_TYPE}")
    endif ()
endif ()

# make sure that debug versions for targets are used (if provided) in Debug mode
set_property(GLOBAL APPEND PROPERTY DEBUG_CONFIGURATIONS Debug)

# Use C++17 if available
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED OFF)

message(STATUS "[${PROJECT_NAME}] Project version: ${PROJECT_VERSION}")

# FetchContent defines FetchContent_Declare() and FetchContent_MakeAvailable()
# which are used to download some dependencies
include(FetchContent)

# GNUInstallDirs defines variables such as BINDIR, SBINDIR, SYSCONFDIR, etc.
# that are substituted when generating defaults.cpp below
include(GNUInstallDirs)

# Make sure that CMake can find our internal modules
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# Options that control the generation of several targets
option(FILE_OPTIONS_BUILD_TESTS "Build tests")


# ##############################################################################
# Check for and/or download dependencies
# ##############################################################################

### some dependencies don't provide CMake modules, but rely on pkg-config
### instead, make sure that pkg-config is available
find_package(PkgConfig REQUIRED)

### boost libraries: required for boost/any.hpp and boost/variant.hpp
message(STATUS "[${PROJECT_NAME}] Checking for boost libraries")
find_package(Boost 1.53 REQUIRED)


### yaml-cpp: required for reading configuration files
message(STATUS "[${PROJECT_NAME}] Checking for yaml-cpp")
find_package(YAMLCpp 0.6.2 REQUIRED)


# Define the file_options library, its includes and needed files
add_library(file_options INTERFACE)

target_sources(file_options INTERFACE
        ${PROJECT_SOURCE_DIR}/include/file_options/file_options.hpp
        ${PROJECT_SOURCE_DIR}/include/file_options/options_description.hpp
        ${PROJECT_SOURCE_DIR}/include/file_options/schema.hpp
        ${PROJECT_SOURCE_DIR}/include/file_options/yaml_parser.hpp
        )

target_include_directories(file_options
        INTERFACE
        $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)

target_link_libraries(file_options INTERFACE YAMLCpp::YAMLCpp)

add_library(file_options::file_options ALIAS file_options)


if (FILE_OPTIONS_BUILD_TESTS)
    enable_testing()
    add_subdirectory(tests)
endif ()
+117 −0
Original line number Diff line number Diff line
################################################################################
# Copyright 2017-2022, Barcelona Supercomputing Center (BSC), Spain            #
#                                                                              #
# This file is part of file_options.                                           #
#                                                                              #
# file_options is free software: you can redistribute it and/or modify         #
# it under the terms of the GNU General Public License as published by         #
# the Free Software Foundation, either version 3 of the License, or            #
# (at your option) any later version.                                          #
#                                                                              #
# file_options is distributed in the hope that it will be useful,              #
# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
# GNU General Public License for more details.                                 #
#                                                                              #
# You should have received a copy of the GNU General Public License            #
# along with file_options.  If not, see <https://www.gnu.org/licenses/>.       #
#                                                                              #
# SPDX-License-Identifier: GPL-3.0-or-later                                    #
################################################################################

#[=======================================================================[.rst:
FindYAMLCpp
---------

Find yaml-cpp include dirs and libraries.

Use this module by invoking find_package with the form::

  find_package(YAMLCpp
    [version] [EXACT]     # Minimum or EXACT version e.g. 0.6.2
    [REQUIRED]            # Fail with error if yaml-cpp is not found
    )

Imported Targets
^^^^^^^^^^^^^^^^

This module provides the following imported targets, if found:

``YAMLCpp::YAMLCpp``
  The YAMLCpp library

Result Variables
^^^^^^^^^^^^^^^^

This will define the following variables:

``YAMLCpp_FOUND``
  True if the system has the YAMLCpp library.
``YAMLCpp_VERSION``
  The version of the YAMLCpp library which was found.
``YAMLCpp_INCLUDE_DIRS``
  Include directories needed to use YAMLCpp.
``YAMLCpp_LIBRARIES``
  Libraries needed to link to YAMLCpp.

Cache Variables
^^^^^^^^^^^^^^^

The following cache variables may also be set:

``YAMLCpp_INCLUDE_DIR``
  The directory containing ``yaml.h``.
``YAMLCpp_LIBRARY``
  The path to the YAMLCpp library.

#]=======================================================================]

# yaml-cpp already provides a config file, but sadly it doesn't define
# a target with the appropriate properties. Fortunately, it also provides a
# pkg-config .pc file that we can use to fetch the required library properties
# and wrap them neatly into the 'YAMLCpp' target we provide
find_package(PkgConfig)
pkg_check_modules(PC_YAMLCpp QUIET yaml-cpp)

find_path(YAMLCpp_INCLUDE_DIR
  NAMES yaml-cpp/yaml.h
  PATHS ${PC_YAMLCpp_INCLUDE_DIRS}
  PATH_SUFFIXES YAMLCpp
)

find_library(YAMLCpp_LIBRARY
  NAMES yaml-cpp
  PATHS ${PC_YAMLCpp_LIBRARY_DIRS}
)

mark_as_advanced(
  YAMLCpp_INCLUDE_DIR
  YAMLCpp_LIBRARY
)

set(YAMLCpp_VERSION ${PC_YAMLCpp_VERSION})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(YAMLCpp
  FOUND_VAR YAMLCpp_FOUND
  REQUIRED_VARS
    YAMLCpp_LIBRARY
    YAMLCpp_INCLUDE_DIR
  VERSION_VAR YAMLCpp_VERSION
)

if(YAMLCpp_FOUND)
  set(YAMLCpp_LIBRARIES ${YAMLCpp_LIBRARY})
  set(YAMLCpp_INCLUDE_DIRS ${YAMLCpp_INCLUDE_DIR})
  set(YAMLCpp_DEFINITIONS ${PC_YAMLCpp_CFLAGS_OTHER})
endif()

if(YAMLCpp_FOUND AND NOT TARGET YAMLCpp::YAMLCpp)
  add_library(YAMLCpp::YAMLCpp UNKNOWN IMPORTED)
  set_target_properties(YAMLCpp::YAMLCpp PROPERTIES
    IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
    IMPORTED_LOCATION "${YAMLCpp_LIBRARY}"
    INTERFACE_COMPILE_DEFINITIONS "${PC_YAMLCpp_CFLAGS_OTHER}"
    INTERFACE_INCLUDE_DIRECTORIES "${YAMLCpp_INCLUDE_DIR}"
)
endif()
+29 −0
Original line number Diff line number Diff line
/******************************************************************************
 * Copyright 2017-2022, Barcelona Supercomputing Center (BSC), Spain
 *
 * This file is part of file_options.
 *
 * file_options is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * file_options is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with file_options.  If not, see <https://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *****************************************************************************/

#ifndef FILE_OPTIONS_FILE_OPTIONS_HPP
#define FILE_OPTIONS_FILE_OPTIONS_HPP

#include "schema.hpp"
#include "options_description.hpp"
#include "yaml_parser.hpp"

#endif /* FILE_OPTIONS_FILE_OPTIONS_HPP */
+123 −0
Original line number Diff line number Diff line
/******************************************************************************
 * Copyright 2021, Barcelona Supercomputing Center (BSC), Spain
 *
 * This software was partially supported by the EuroHPC-funded project ADMIRE
 *   (Project ID: 956748, https://www.admire-eurohpc.eu).
 *
 * This file is part of file_options.
 *
 * file_options is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * file_options is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with file_options.  If not, see <https://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *****************************************************************************/

/*
 * This file contains the code to implement an options map that can
 * be generated by parsing a configuration according to the structure
 * defined by a file_schema instance.
 */

#ifndef FILE_OPTIONS_OPTIONS_DESCRIPTION_HPP
#define FILE_OPTIONS_OPTIONS_DESCRIPTION_HPP

#include <yaml-cpp/yaml.h>
#include <boost/any.hpp>
#include <utility>

namespace file_options {

/*! Class to handle values of an arbitrary type */
struct option_value {
    /*! Constructor. The 'value' parameter is  passed (and stored)
     * as boost::any in order to handle arbitrarily-typed values */
    explicit option_value(boost::any value) : m_value(std::move(value)) {}

    /*! If the stored value is of type T, returns that value.
     * Otherwise throws boost::bad_any_cast exception */
    template <typename T>
    T&
    get_as() {
        return boost::any_cast<T&>(m_value);
    }

    /*! If the stored value is of type T, returns that value.
     * Otherwise throws boost::bad_any_cast exception */
    template <typename T>
    const T&
    get_as() const {
        return boost::any_cast<const T&>(m_value);
    }

    /*! Stored option value */
    boost::any m_value;
};

/*! Class to handle a group of related options. The stored options
 * can be accessed using the usual std::map interface. */
struct options_group : public std::map<std::string, option_value> {

    bool
    has(const std::string& opt_name) const {
        return count(opt_name) != 0;
    }

    /*! If the options_group contains an option named 'opt_name'
     * of type T, returns the value for that option.
     * If the option does not exist, throws std::invalid_argument exception.
     * Otherwise throws boost::bad_any_cast exception */
    template <typename T>
    const T&
    get_as(const std::string& opt_name) const {

        auto it = find(opt_name);

        if(it == end()) {
            throw std::invalid_argument("option '" + opt_name + "' missing");
        }

        return it->second.get_as<T>();
    }
};

/*! Class to handle a list of several groups */
using options_list = std::vector<options_group>;

/*! Class that stores the values for the defined variables so that they
 * can be accessed in a key-value manner.
 * This class is derived from std::map<std::string, boost::any>,
 * therefore all usual std::map operators can be used to access
 * its contents */
struct options_map : public std::map<std::string, boost::any> {

    /*! If the options_map contains an option named 'opt_name'
     * of type T, returns the value for that option.
     * If the option does not exist, throws std::invalid_argument exception.
     * Otherwise throws boost::bad_any_cast exception */
    template <typename T>
    T&
    get_as(const std::string& opt_name) {

        auto it = find(opt_name);

        if(it == end()) {
            throw std::invalid_argument("option '" + opt_name + "' missing");
        }

        return boost::any_cast<T&>(it->second);
    }
};

} // namespace file_options

#endif /* FILE_OPTIONS_OPTIONS_DESCRIPTION_HPP */
+414 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading