DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
oks_check_schema.cxx File Reference
#include "CLI/CLI.hpp"
#include "logging/Logging.hpp"
#include "oks/class.hpp"
#include "oks/file.hpp"
#include "oks/kernel.hpp"
#include "oks/relationship.hpp"
#include <fmt/core.h>
#include <set>
#include <string>
Include dependency graph for oks_check_schema.cxx:

Go to the source code of this file.

Functions

int main (int argc, char **argv)

Detailed Description

Program to do some simple integrity checks on a schema file

This is part of the DUNE DAQ Application Framework, copyright 2025. Licensing/copyright details are in the COPYING file that you should have received with this code.

Definition in file oks_check_schema.cxx.

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 25 of file oks_check_schema.cxx.

26{
27 enum Exitcode : int
28 {
29 SUCCESS,
30 BADCMD,
31 NOFILE,
32 LOADFAIL,
33 BADRELATIONSHIP,
34 UNRESOLVED,
35 MISSING_INCLUDE
36 };
37
38 CLI::App app{
39 "Check consistency of OKS schema file\n" +
40 fmt::format("Return codes: {} Success, file is OK\n", Exitcode::SUCCESS) +
41 fmt::format(" {} Bad command line\n", Exitcode::BADCMD) +
42 fmt::format(" {} Failed to find file\n", Exitcode::NOFILE) +
43 fmt::format(" {} Failed to load file -- invalid schema\n", Exitcode::LOADFAIL) +
44 fmt::format(" {} File contains relationship to non loaded class\n", Exitcode::BADRELATIONSHIP) +
45 fmt::format(" {} File contains object with relationship to non loaded class/object\n",
46 Exitcode::UNRESOLVED) +
47 fmt::format(" {} File refers to class in file not directly included\n", Exitcode::MISSING_INCLUDE)
48 };
49
50 std::string filename;
51 app.add_option("-f,--file", filename, "Schema file")->required();
52
53 CLI11_PARSE(app, argc, argv);
54
55 OksKernel kernel;
56 OksFile* file{ nullptr };
57 try {
58 file = kernel.load_file(filename);
59 } catch (FailedLoadFile& fail) {
60 TLOG() << fail.what() << "\n";
61 return Exitcode::LOADFAIL;
62 } catch (CanNotOpenFile& fail) {
63 TLOG() << fail.what() << "\n";
64 return Exitcode::NOFILE;
65 } catch (std::exception& exc) {
66 TLOG() << exc.what() << "\n";
67 return Exitcode::LOADFAIL;
68 }
69
70 if (file == nullptr) {
71 TLOG() << "Failed to load " << filename;
72 return Exitcode::LOADFAIL;
73 }
74
75 std::set<std::string> includes;
76 for (const auto& ifile : file->get_include_files()) {
77 includes.insert(ifile);
78 TLOG_DEBUG(2) << "direct inserting " << ifile << "\n";
79 }
80
81 Exitcode result = Exitcode::SUCCESS;
82
83 if (filename.ends_with(".schema.xml")) {
84 // Check classes defined in this schema file
85 for (auto [name, oks_class] : kernel.classes()) {
86
87 if (file->get_full_file_name() != oks_class->get_file()->get_full_file_name()) {
88 // Class not defined in this file
89 continue;
90 }
91
92 auto cfile = oks_class->get_file()->get_short_file_name();
93 if (cfile != file->get_short_file_name() && !includes.contains(cfile)) {
94 TLOG() << "Error " << filename << " misses include of " << cfile << " required by " << name;
95 if (result == Exitcode::SUCCESS) {
96 result = Exitcode::MISSING_INCLUDE;
97 }
98 }
99 auto relationships = oks_class->direct_relationships();
100 if (relationships != nullptr) {
101 for (auto rel : *relationships) {
102 auto rel_class = rel->get_class_type();
103 if (rel_class == nullptr) {
104 TLOG() << "Error class '" << name << "' has relationship '" << rel->get_name() << "' to a class '"
105 << rel->get_type() << "' that is not loaded\n";
106 if (result == Exitcode::SUCCESS) {
107 result = Exitcode::BADRELATIONSHIP;
108 }
109 }
110 }
111 }
112 // Could check super-classes but we wouldn't have got past the
113 // load if they referred to a missing class.
114 }
115 } else if (filename.ends_with(".data.xml")) {
116
117 auto check_relationship = [&](OksData* data) {
118 auto relobj = data->data.OBJECT;
119 if (relobj == nullptr) {
120 return;
121 }
122 auto ofile_name = relobj->get_file()->get_short_file_name();
123 if (file->get_short_file_name() != ofile_name && !includes.contains(ofile_name)) {
124 TLOG() << "Error " << filename << " misses include of " << ofile_name << " required by " << relobj->GetId();
125 if (result == Exitcode::SUCCESS) {
126 result = Exitcode::MISSING_INCLUDE;
127 }
128 }
129 };
130
131 auto data_objs = kernel.create_list_of_data_objects(file);
132 for (auto obj : *data_objs) {
133 // Check that any objects defined in this data file have their
134 // corresponding schema file included directly in this file
135 auto oks_class = obj->GetClass();
136 auto cfile = oks_class->get_file()->get_short_file_name();
137 if (!includes.contains(cfile)) {
138 TLOG() << "Error " << filename << " misses include of " << cfile << " required by " << obj->GetId()
139 << " of class " << oks_class->get_name();
140 if (result == Exitcode::SUCCESS) {
141 result = Exitcode::MISSING_INCLUDE;
142 }
143 }
144
145 // Check that any objects referenced by objects in this file are
146 // either defined in this file or one that is directly included
147 auto relationships = oks_class->all_relationships();
148 if (relationships != nullptr) {
149 for (auto rel : *relationships) {
150 auto relval = obj->GetRelationshipValue(rel->get_name());
151 if (relval == nullptr) {
152 continue;
153 }
154 if (rel->get_high_cardinality_constraint() == OksRelationship::Many) {
155 for (OksData::List::iterator iter = relval->data.LIST->begin(); iter != relval->data.LIST->end(); ++iter) {
156 check_relationship(*iter);
157 }
158 } else {
159 check_relationship(relval);
160 }
161 }
162 }
163 }
164 delete data_objs;
165 }
166
167 auto status = kernel.get_bind_objects_status();
168 if (!status.empty()) {
169 if (result == Exitcode::SUCCESS) {
170 result = Exitcode::UNRESOLVED;
171 }
172 }
173
174 return result;
175}
Cannot open file.
Definition kernel.hpp:145
Cannot load file.
Definition kernel.hpp:60
Provides interface to the OKS XML schema and data files.
Definition file.hpp:355
Provides interface to the OKS kernel.
Definition kernel.hpp:615
OksFile * load_file(const std::string &name, bool bind=true)
Load OKS database file.
Definition kernel.cpp:1625
std::list< OksObject * > * create_list_of_data_objects(OksFile *) const
Creates list of objects which belong to given file.
Definition kernel.cpp:4106
const OksClass::Map & classes() const
Get classes.
Definition kernel.hpp:1711
const std::string & get_bind_objects_status() const noexcept
Return status of oks objects binding.
Definition kernel.hpp:1922
virtual const char * what() const noexcept
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:116
#define TLOG(...)
Definition macro.hpp:21
Struct OKS data.
Definition object.hpp:510