Compare commits

..

9 Commits

Author SHA1 Message Date
Bartek Kryza
eded9f4292 Fixed template API warning 2023-07-24 19:41:04 +02:00
Bartek Kryza
9df58ca251 Merge pull request #171 from bkryza/add-configuration-file-validation
Add configuration file validation
2023-07-23 18:59:12 +02:00
Bartek Kryza
bcd32bfd41 Fixed building on MSVC 2023-07-23 18:34:03 +02:00
Bartek Kryza
366bb19912 Minor configuration schema updates 2023-07-23 17:07:22 +02:00
Bartek Kryza
18c4031047 Added schema validation command line flags 2023-07-23 13:12:17 +02:00
Bartek Kryza
ec0079d876 Added include/exclude filter specification to validator schema 2023-07-23 01:22:14 +02:00
Bartek Kryza
8dc0dacd3f Added initial configuration file schema validation 2023-07-22 18:39:07 +02:00
Bartek Kryza
97efbbb332 Added miroir yaml validation library 2023-07-22 18:36:37 +02:00
Bartek Kryza
561a2b16fd Merge pull request #170 from bkryza/v0.3.8
V0.3.8
2023-07-09 17:28:19 +02:00
18 changed files with 2844 additions and 88 deletions

View File

@@ -443,6 +443,7 @@ This project relies on the following great tools:
* [spdlog](https://github.com/gabime/spdlog) - Fast C++ logging library
* [Doxygen](https://www.doxygen.nl/) - C++ documentation generator
* [Doxygen Awesome](https://jothepro.github.io/doxygen-awesome-css) - Doxygen CSS style
* [miroir](https://gitlab.com/madyanov/miroir) - YAML schema validation library for C++
## Contributing

View File

@@ -11,7 +11,6 @@ diagrams:
- ../../tests/t00048/a_t00048.cc
- ../../tests/t00048/t00048.cc
using_namespace: clanguml::t00048
parse_includes: true
include:
namespaces:
- clanguml::t00048

View File

@@ -200,6 +200,13 @@ the configuration file to `clang-uml` using `stdin`, e.g.:
yq 'explode(.)' .clang-uml | clang-uml --config -
```
## Schema validation error is thrown, but the configuration file is correct
Current version of `clang-uml` performs automatic configuration file
schema validation, and exits if the configuration file is invalid.
In case there is a bug in the schema validation, the schema validation
step can be skipped by providing `--no-validate` command line option.
## Class diagrams
### "fatal error: 'stddef.h' file not found"

View File

@@ -131,6 +131,10 @@ cli_flow_t cli_handler::parse(int argc, const char **argv)
"Skip metadata (e.g. clang-uml version) from diagrams");
app.add_flag("--print-start-from", print_start_from,
"Print all possible 'start_from' values for a given diagram");
app.add_flag("--no-validate", no_validate,
"Do not perform configuration file schema validation");
app.add_flag("--validate-only", validate_only,
"Perform configuration file schema validation and exit");
try {
app.parse(argc, argv);
@@ -245,7 +249,13 @@ cli_flow_t cli_handler::load_config()
{
try {
config = clanguml::config::load(
config_path, paths_relative_to_pwd, no_metadata);
config_path, paths_relative_to_pwd, no_metadata, !no_validate);
if (validate_only) {
std::cout << "Configuration file " << config_path << " is valid.\n";
return cli_flow_t::kExit;
}
return cli_flow_t::kContinue;
}
catch (std::runtime_error &e) {
@@ -275,7 +285,7 @@ cli_flow_t cli_handler::handle_post_config_options()
if (config_path != "-" && add_diagram_from_template) {
return add_config_diagram_from_template(
config_path, add_diagram_from_template.value(), template_variables);
config_path, add_diagram_from_template.value());
}
LOG_INFO("Loaded clang-uml config from {}", config_path);
@@ -559,8 +569,7 @@ cli_flow_t cli_handler::add_config_diagram(
}
cli_flow_t cli_handler::add_config_diagram_from_template(
const std::string &config_file_path, const std::string &template_name,
const std::vector<std::string> &template_variables)
const std::string &config_file_path, const std::string &template_name)
{
if (!config.diagram_templates ||
!(config.diagram_templates().find(template_name) !=

View File

@@ -128,14 +128,12 @@ public:
/**
* Add diagram based on template
*
* @param config_file_path
* @param template_name
* @param template_variables
* @param config_file_path Path to the configuration file
* @param template_name Name of the diagram template
* @return Command line handler state
*/
cli_flow_t add_config_diagram_from_template(
const std::string &config_file_path, const std::string &template_name,
const std::vector<std::string> &template_variables);
const std::string &config_file_path, const std::string &template_name);
/**
* Check if diagram output directory exists, if not create it
@@ -183,6 +181,8 @@ public:
std::optional<std::string> show_template;
std::vector<clanguml::common::generator_type_t> generators{
clanguml::common::generator_type_t::plantuml};
bool no_validate{false};
bool validate_only{false};
clanguml::config::config config;

View File

@@ -140,6 +140,32 @@ std::string to_string(location_t cp)
}
}
std::string to_string(package_type_t pt)
{
switch (pt) {
case package_type_t::kNamespace:
return "namespace";
case package_type_t::kDirectory:
return "directory";
default:
assert(false);
return "";
}
}
std::string to_string(member_order_t mo)
{
switch (mo) {
case member_order_t::lexical:
return "lexical";
case member_order_t::as_is:
return "as_is";
default:
assert(false);
return "";
}
}
void plantuml::append(const plantuml &r)
{
before.insert(before.end(), r.before.begin(), r.before.end());

View File

@@ -36,6 +36,10 @@
namespace clanguml {
namespace cli {
struct runtime_config;
} // namespace cli
/**
* @brief Configuration file related classes
*
@@ -50,6 +54,8 @@ enum class method_arguments {
none /*! Empty string between '(' and ')' */
};
std::string to_string(method_arguments ma);
/*! Types of methods, which can be used in diagram filters */
enum class method_type {
constructor,
@@ -84,6 +90,8 @@ enum class package_type_t {
kDirectory /*!< From directories */
};
std::string to_string(package_type_t mt);
/*! How class methods and members should be ordered in diagrams */
enum class member_order_t {
lexical, /*! Lexical order based on entire method or member signature
@@ -91,7 +99,7 @@ enum class member_order_t {
as_is /*! As written in source code */
};
std::string to_string(method_arguments ma);
std::string to_string(member_order_t mt);
/*! Which comment parser should be used */
enum class comment_parser_t {
@@ -413,6 +421,8 @@ struct source_location {
* @embed{inheritable_diagram_options_context_class.svg}
*/
struct inheritable_diagram_options {
virtual ~inheritable_diagram_options() = default;
option<std::vector<std::string>> glob{"glob"};
option<common::model::namespace_> using_namespace{"using_namespace"};
option<bool> include_relations_also_as_members{
@@ -424,7 +434,7 @@ struct inheritable_diagram_options {
"generate_method_arguments", method_arguments::full};
option<bool> group_methods{"group_methods", true};
option<member_order_t> member_order{
"method_order", member_order_t::lexical};
"member_order", member_order_t::lexical};
option<bool> generate_packages{"generate_packages", false};
option<package_type_t> package_type{
"package_type", package_type_t::kNamespace};
@@ -466,7 +476,7 @@ struct inheritable_diagram_options {
* @embed{diagram_config_hierarchy_class.svg}
*/
struct diagram : public inheritable_diagram_options {
virtual ~diagram() = default;
~diagram() override = default;
virtual common::model::diagram_t type() const = 0;
@@ -616,13 +626,12 @@ struct config : public inheritable_diagram_options {
* the configuration file or to the current
* directory (`$PWD`)
* @param no_metadata Whether the diagram should skip metadata at the end
* @param validate If true, perform schema validation
* @return Configuration instance
*/
config load(const std::string &config_file,
std::optional<bool> paths_relative_to_pwd = {},
std::optional<bool> no_metadata = {});
config load_plain(const std::string &config_file);
std::optional<bool> no_metadata = {}, bool validate = true);
} // namespace config

295
src/config/schema.h Normal file
View File

@@ -0,0 +1,295 @@
/**
* @file src/config/schema.h
*
* Copyright (c) 2021-2023 Bartek Kryza <bkryza@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <string>
namespace clanguml::config {
const std::string schema_str = R"(
types:
map_t<K;V>: { $K: V }
comment_parser_t: !variant
- plain
- clang
diagram_type_t: !variant
- class
- sequence
- include
- package
generate_method_arguments_t: !variant
- full
- abbreviated
- none
generate_links_t:
link: string
tooltip: string
git_t:
branch: string
revision: string
commit: string
toplevel: string
layout_hint_key: !variant
- up
- left
- right
- down
- row
- column
- together
layout_hint_value: [string, [string]]
layout_hint_t: [map_t<layout_hint_key;layout_hint_value>]
layout_t: map_t<string;layout_hint_t>
package_type_t: !variant
- namespace
- directory
member_order_t: !variant
- lexical
- as_is
regex_t:
r: string
regex_or_string_t: [string, regex_t]
namespaces_filter_t:
namespaces: [regex_or_string_t]
elements_filter_t:
elements: [regex_or_string_t]
element_types_filter_t: !variant
- class
- enum
- concept
- method
- function
- function_template
- lambda
relationship_filter_t: !variant
- extension
- inheritance
- composition
- aggregation
- containment
- ownership
- association
- instantiation
- friendship
- alias
- dependency
- constraint
- none
access_filter_t: !variant
- public
- protected
- private
method_type_filter_t: !variant
- constructor
- destructor
- assignment
- operator
- defaulted
- deleted
- static
callee_type_filter_t: !variant
- constructor
- assignment
- operator
- defaulted
- static
- method
- function
- function_template
- lambda
filter_t:
namespaces: !optional [regex_or_string_t]
elements: !optional [regex_or_string_t]
element_types: !optional [element_types_filter_t]
relationships: !optional [relationship_filter_t]
access: !optional [access_filter_t]
subclasses: !optional [regex_or_string_t]
parents: !optional [regex_or_string_t]
specializations: !optional [regex_or_string_t]
dependants: !optional [regex_or_string_t]
dependencies: !optional [regex_or_string_t]
context: !optional [regex_or_string_t]
paths: !optional [string]
method_types: !optional [method_type_filter_t]
callee_types: !optional [callee_type_filter_t]
function_location_t:
function: string
marker_location_t:
marker: string
source_location_t:
- function_location_t
- marker_location_t
class_diagram_t:
type: !variant [class]
#
# Common options
#
__parent_path: !optional string
comment_parser: !optional comment_parser_t
debug_mode: !optional bool
exclude: !optional filter_t
generate_links: !optional generate_links_t
git: !optional git_t
glob: !optional [string]
include: !optional filter_t
plantuml: !optional
before: !optional [string]
after: !optional [string]
relative_to: !optional string
using_namespace: !optional [string, [string]]
generate_metadata: !optional bool
#
# Class diagram specific options
#
generate_method_arguments: !optional generate_method_arguments_t
generate_packages: !optional bool
package_type: !optional package_type_t
member_order: !optional member_order_t
group_methods: !optional bool
type_aliases: !optional map_t<string;string>
relationship_hints: !optional map_t<string;any>
include_relations_also_as_members: !optional bool
layout: !optional layout_t
sequence_diagram_t:
type: !variant [sequence]
#
# Common options
#
__parent_path: !optional string
comment_parser: !optional comment_parser_t
debug_mode: !optional bool
exclude: !optional filter_t
generate_links: !optional generate_links_t
git: !optional git_t
glob: !optional [string]
include: !optional filter_t
plantuml: !optional
before: !optional [string]
after: !optional [string]
relative_to: !optional string
using_namespace: !optional [string, [string]]
generate_metadata: !optional bool
#
# Sequence diagram specific options
#
generate_method_arguments: !optional generate_method_arguments_t
combine_free_functions_into_file_participants: !optional bool
generate_return_types: !optional bool
generate_condition_statements: !optional bool
participants_order: !optional [string]
start_from: !optional [source_location_t]
package_diagram_t:
type: !variant [package]
#
# Common options
#
__parent_path: !optional string
comment_parser: !optional comment_parser_t
debug_mode: !optional bool
exclude: !optional filter_t
generate_links: !optional generate_links_t
git: !optional git_t
glob: !optional [string]
include: !optional filter_t
plantuml: !optional
before: !optional [string]
after: !optional [string]
relative_to: !optional string
using_namespace: !optional [string, [string]]
generate_metadata: !optional bool
#
# Package diagram specific options
#
generate_packages: !optional bool
package_type: !optional package_type_t
layout: !optional layout_t
include_diagram_t:
type: !variant [include]
#
# Common options
#
__parent_path: !optional string
comment_parser: !optional comment_parser_t
debug_mode: !optional bool
exclude: !optional filter_t
generate_links: !optional generate_links_t
git: !optional git_t
glob: !optional [string]
include: !optional filter_t
plantuml: !optional
before: !optional [string]
after: !optional [string]
relative_to: !optional string
using_namespace: !optional [string, [string]]
generate_metadata: !optional bool
#
# Include diagram specific options
#
generate_system_headers: !optional bool
diagram_t:
- class_diagram_t
- sequence_diagram_t
- package_diagram_t
- include_diagram_t
diagram_template_t:
description: !optional string
type: diagram_type_t
template: string
diagram_templates_t: map_t<string;diagram_template_t>
root:
#
# Root options
#
compilation_database_dir: !optional string
output_directory: !optional string
add_compile_flags: !optional [string]
remove_compile_flags: !optional [string]
diagram_templates: !optional diagram_templates_t
diagrams: !required map_t<string;diagram_t>
#
# Common options
#
__parent_path: !optional string
comment_parser: !optional comment_parser_t
debug_mode: !optional bool
exclude: !optional filter_t
generate_links: !optional generate_links_t
git: !optional git_t
glob: !optional [string]
include: !optional filter_t
plantuml: !optional
before: !optional [string]
after: !optional [string]
relative_to: !optional string
using_namespace: !optional [string, [string]]
generate_metadata: !optional bool
#
# Inheritable custom options
#
include_relations_also_as_members: !optional bool
generate_method_arguments: !optional generate_method_arguments_t
combine_free_functions_into_file_participants: !optional bool
generate_return_types: !optional bool
generate_condition_statements: !optional bool
generate_packages: !optional bool
group_methods: !optional bool
package_type: !optional package_type_t
)";
} // namespace clanguml::config

View File

@@ -16,8 +16,14 @@
* limitations under the License.
*/
#include "cli/cli_handler.h"
#include "config.h"
#include "diagram_templates.h"
#include "schema.h"
#define MIROIR_IMPLEMENTATION
#define MIROIR_YAMLCPP_SPECIALIZATION
#include <miroir/miroir.hpp>
namespace YAML {
using clanguml::common::namespace_or_regex;
@@ -766,28 +772,13 @@ template <> struct convert<config> {
auto diagrams = node["diagrams"];
assert(diagrams.Type() == NodeType::Map);
for (auto d : diagrams) {
auto name = d.first.as<std::string>();
std::shared_ptr<clanguml::config::diagram> diagram_config{};
auto parent_path = node["__parent_path"].as<std::string>();
d.second.force_insert("__parent_path", parent_path);
if (has_key(d.second, "include!")) {
auto include_path = std::filesystem::path{parent_path};
include_path /= d.second["include!"].as<std::string>();
YAML::Node included_node =
YAML::LoadFile(include_path.string());
included_node.force_insert("__parent_path", parent_path);
diagram_config = parse_diagram_config(included_node);
}
else {
d.second.force_insert("__parent_path", parent_path);
diagram_config = parse_diagram_config(d.second);
}
diagram_config = parse_diagram_config(d.second);
if (diagram_config) {
diagram_config->name = name;
diagram_config->inherit(rhs);
@@ -841,9 +832,13 @@ void resolve_option_path(YAML::Node &doc, const std::string &option)
} // namespace
config load(const std::string &config_file,
std::optional<bool> paths_relative_to_pwd, std::optional<bool> no_metadata)
std::optional<bool> paths_relative_to_pwd, std::optional<bool> no_metadata,
bool validate)
{
try {
auto schema = YAML::Load(clanguml::config::schema_str);
auto schema_validator = miroir::Validator<YAML::Node>(schema);
YAML::Node doc;
std::filesystem::path config_file_path{};
@@ -860,6 +855,8 @@ config load(const std::string &config_file,
// Store the parent path of the config_file to properly resolve
// the include files paths
if (has_key(doc, "__parent_path"))
doc.remove("__parent_path");
if (config_file == "-") {
config_file_path = std::filesystem::current_path();
doc.force_insert("__parent_path", config_file_path.string());
@@ -914,6 +911,40 @@ config load(const std::string &config_file,
doc["git"] = git_config;
}
// Resolve diagram includes
auto diagrams = doc["diagrams"];
assert(diagrams.Type() == YAML::NodeType::Map);
for (auto d : diagrams) {
auto name = d.first.as<std::string>();
std::shared_ptr<clanguml::config::diagram> diagram_config{};
auto parent_path = doc["__parent_path"].as<std::string>();
if (has_key(d.second, "include!")) {
auto include_path = std::filesystem::path{parent_path};
include_path /= d.second["include!"].as<std::string>();
YAML::Node included_node =
YAML::LoadFile(include_path.string());
diagrams[name] = included_node;
}
}
if (validate) {
auto schema_errors = schema_validator.validate(doc);
if (!schema_errors.empty()) {
// print validation errors
for (const auto &err : schema_errors) {
LOG_ERROR("Schema error: {}", err.description());
}
throw YAML::Exception({}, "Invalid configuration schema");
}
}
auto d = doc.as<config>();
d.initialize_diagram_templates();
@@ -929,25 +960,4 @@ config load(const std::string &config_file,
"Cannot parse YAML file {}: {}", config_file, e.what()));
}
}
config load_plain(const std::string &config_file)
{
try {
YAML::Node doc;
std::filesystem::path config_file_path{};
doc = YAML::LoadFile(config_file);
auto d = doc.as<config>();
return d;
}
catch (YAML::BadFile &e) {
throw std::runtime_error(fmt::format(
"Could not open config file {}: {}", config_file, e.what()));
}
catch (YAML::Exception &e) {
throw std::runtime_error(fmt::format(
"Cannot parse YAML file {}: {}", config_file, e.what()));
}
}
} // namespace clanguml::config

View File

@@ -26,8 +26,10 @@ YAML::Emitter &operator<<(YAML::Emitter &out, const string_or_regex &m)
out << std::get<std::string>(m.value());
}
else {
out << YAML::BeginMap;
out << YAML::Key << "r" << YAML::Value
<< std::get<regex>(m.value()).pattern;
out << YAML::EndMap;
}
return out;
@@ -39,8 +41,10 @@ YAML::Emitter &operator<<(YAML::Emitter &out, const namespace_or_regex &m)
out << std::get<common::model::namespace_>(m.value());
}
else {
out << YAML::BeginMap;
out << YAML::Key << "r" << YAML::Value
<< std::get<regex>(m.value()).pattern;
out << YAML::EndMap;
}
return out;
@@ -88,6 +92,18 @@ YAML::Emitter &operator<<(YAML::Emitter &out, const callee_type &m)
return out;
}
YAML::Emitter &operator<<(YAML::Emitter &out, const member_order_t &r)
{
out << to_string(r);
return out;
}
YAML::Emitter &operator<<(YAML::Emitter &out, const package_type_t &r)
{
out << to_string(r);
return out;
}
YAML::Emitter &operator<<(YAML::Emitter &out, const filter &f)
{
out << YAML::BeginMap;
@@ -267,32 +283,50 @@ YAML::Emitter &operator<<(YAML::Emitter &out, const config &c)
YAML::Emitter &operator<<(
YAML::Emitter &out, const inheritable_diagram_options &c)
{
out << c.glob;
out << c.using_namespace;
out << c.include_relations_also_as_members;
out << c.include;
// Common options
out << c.base_directory;
out << c.comment_parser;
out << c.debug_mode;
out << c.exclude;
out << c.puml;
out << c.generate_method_arguments;
out << c.generate_packages;
out << c.generate_links;
out << c.git;
out << c.base_directory;
out << c.glob;
out << c.include;
out << c.puml;
out << c.relative_to;
out << c.generate_system_headers;
if (c.relationship_hints) {
out << YAML::Key << "relationship_hints" << YAML::Value
<< c.relationship_hints();
out << c.using_namespace;
out << c.generate_metadata;
if (dynamic_cast<const class_diagram *>(&c) != nullptr) {
out << c.generate_method_arguments;
out << c.generate_packages;
out << c.include_relations_also_as_members;
if (c.relationship_hints) {
out << YAML::Key << "relationship_hints" << YAML::Value
<< c.relationship_hints();
}
if (c.type_aliases) {
out << YAML::Key << "type_aliases" << YAML::Value
<< c.type_aliases();
}
out << c.member_order;
out << c.package_type;
}
if (c.type_aliases) {
out << YAML::Key << "type_aliases" << YAML::Value << c.type_aliases();
else if (dynamic_cast<const sequence_diagram *>(&c) != nullptr) {
out << c.combine_free_functions_into_file_participants;
out << c.generate_condition_statements;
out << c.generate_method_arguments;
out << c.generate_return_types;
out << c.participants_order;
}
else if (dynamic_cast<const package_diagram *>(&c) != nullptr) {
out << c.generate_packages;
out << c.package_type;
}
else if (dynamic_cast<const include_diagram *>(&c) != nullptr) {
out << c.generate_system_headers;
}
out << c.comment_parser;
out << c.combine_free_functions_into_file_participants;
out << c.generate_return_types;
out << c.generate_condition_statements;
out << c.participants_order;
out << c.debug_mode;
return out;
}

View File

@@ -8,7 +8,6 @@ diagrams:
- ../../tests/t00048/a_t00048.cc
- ../../tests/t00048/t00048.cc
using_namespace: clanguml::t00048
parse_includes: true
include:
namespaces:
- clanguml::t00048

View File

@@ -15,10 +15,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define CATCH_CONFIG_MAIN
#define CATCH_CONFIG_RUNNER
#define CATCH_CONFIG_CONSOLE_WIDTH 512
#include "catch.h"
#include "cli/cli_handler.h"
#include "config/config.h"
#include "util/util.h"
@@ -339,4 +340,45 @@ TEST_CASE("Test config sequence inherited", "[unit-test]")
CHECK(def.type() == clanguml::common::model::diagram_t::kSequence);
CHECK(def.combine_free_functions_into_file_participants() == false);
CHECK(def.generate_return_types() == false);
}
}
TEST_CASE("Test config full clang uml dump", "[unit-test]")
{
auto cfg =
clanguml::config::load("./test_config_data/clang_uml_config.yml");
CHECK(cfg.diagrams.size() == 32);
}
///
/// Main test function
///
int main(int argc, char *argv[])
{
Catch::Session session;
using namespace Catch::clara;
bool debug_log{false};
auto cli = session.cli() |
Opt(debug_log, "debug_log")["-u"]["--debug-log"]("Enable debug logs");
session.cli(cli);
int returnCode = session.applyCommandLine(argc, argv);
if (returnCode != 0)
return returnCode;
clanguml::cli::cli_handler clih;
std::vector<const char *> argvv = {
"clang-uml", "--config", "./test_config_data/simple.yml"};
if (debug_log)
argvv.push_back("-vvv");
else
argvv.push_back("-q");
clih.handle_options(argvv.size(), argvv.data());
return session.run();
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,11 +6,11 @@ diagram_templates:
description: Sequence diagram of the main() function
type: sequence
template: |
main_sequence_diagram:
type: sequence
glob: [ {{ glob }} ]
start_from:
- function: 'main(int,const char**)'
main_sequence_diagram:
type: sequence
glob: [ {{ glob }} ]
start_from:
- function: 'main(int,const char**)'
diagrams:
diagram1:
type: class

View File

@@ -28,7 +28,6 @@ diagrams:
- src/**/*.h
using_namespace:
- clanguml
generate_method_arguments: full
layout:
ABCD:
- up: ABCD_SUBCLASS

21
thirdparty/miroir/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Roman Madyanov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

1152
thirdparty/miroir/miroir.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -12,9 +12,8 @@ include:
subclasses:
- clanguml::common::model::decorated_element
- clanguml::common::model::source_location
include:
relationships:
- inheritance
relationships:
- inheritance
exclude:
relationships:
- dependency