DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
file.cpp
Go to the documentation of this file.
1// DUNE DAQ modification notice:
2// This file has been modified from the original ATLAS oks source for the DUNE DAQ project.
3// Fork baseline commit: oks-08-03-04 (2022-04-14).
4// Renamed since fork: no.
5
6#define _OksBuildDll_
7
8#include "oks/file.hpp"
9#include "oks/cstring.hpp"
10#include "oks/kernel.hpp"
11#include "oks/xml.hpp"
12
13#include "oks_utils.hpp"
14
15#include <errno.h>
16#include <stdlib.h>
17#include <string.h>
18#include <sys/stat.h>
19#include <unistd.h>
20
21#include <fstream>
22#include <sstream>
23#include <stdexcept>
24
25#include <boost/date_time/posix_time/posix_time_types.hpp>
26#include <boost/date_time/posix_time/time_formatters.hpp>
27#include <boost/date_time/posix_time/time_parsers.hpp>
28#include <boost/interprocess/sync/file_lock.hpp>
29
30#include "ers/ers.hpp"
31#include "logging/Logging.hpp"
32
33namespace dunedaq {
34namespace oks {
35// Nasty hack to allow code generation on the fly without locking
36// file. Off by default
37bool OksFile::p_nolock_mode = false;
38//
39// Define XML formats used to store OKS schema and data files
40//
41
42const char OksFile::xml_info_tag[] = "info";
43const char OksFile::xml_include_tag[] = "include";
44const char OksFile::xml_file_tag[] = "file";
45const char OksFile::xml_comments_tag[] = "comments";
46const char OksFile::xml_comment_tag[] = "comment";
47
48const char OksFile::xml_file_header[] = "<?xml version=\"1.0\" encoding=\"ASCII\"?>";
49
51 "<!DOCTYPE oks-schema [\n"
52
53 " <!ELEMENT oks-schema (info, (include)?, (comments)?, (class)+)>\n"
54
55 " <!ELEMENT info EMPTY>\n"
56 " <!ATTLIST info\n"
57 " name CDATA #IMPLIED\n"
58 " type CDATA #IMPLIED\n"
59 " num-of-items CDATA #REQUIRED\n"
60 " oks-format CDATA #FIXED \"schema\"\n"
61 " oks-version CDATA #REQUIRED\n"
62 " created-by CDATA #IMPLIED\n"
63 " created-on CDATA #IMPLIED\n"
64 " creation-time CDATA #IMPLIED\n"
65 " last-modified-by CDATA #IMPLIED\n"
66 " last-modified-on CDATA #IMPLIED\n"
67 " last-modification-time CDATA #IMPLIED\n"
68 " >\n"
69
70 " <!ELEMENT include (file)+>\n"
71 " <!ELEMENT file EMPTY>\n"
72 " <!ATTLIST file\n"
73 " path CDATA #REQUIRED\n"
74 " >\n"
75
76 " <!ELEMENT comments (comment)+>\n"
77 " <!ELEMENT comment EMPTY>\n"
78 " <!ATTLIST comment\n"
79 " creation-time CDATA #REQUIRED\n"
80 " created-by CDATA #REQUIRED\n"
81 " created-on CDATA #REQUIRED\n"
82 " author CDATA #REQUIRED\n"
83 " text CDATA #REQUIRED\n"
84 " >\n"
85
86 " <!ELEMENT class (superclass | attribute | relationship | method)*>\n"
87 " <!ATTLIST class\n"
88 " name CDATA #REQUIRED\n"
89 " description CDATA \"\"\n"
90 " is-abstract (yes|no) \"no\"\n"
91 " >\n"
92
93 " <!ELEMENT superclass EMPTY>\n"
94 " <!ATTLIST superclass name CDATA #REQUIRED>\n"
95
96 " <!ELEMENT attribute EMPTY>\n"
97 " <!ATTLIST attribute\n"
98 " name CDATA #REQUIRED\n"
99 " description CDATA \"\"\n"
100 " type (bool|s8|u8|s16|u16|s32|u32|s64|u64|float|double|date|time|string|uid|enum|class) #REQUIRED\n"
101 " range CDATA \"\"\n"
102 " format (dec|hex|oct) \"dec\"\n"
103 " is-multi-value (yes|no) \"no\"\n"
104 " init-value CDATA \"\"\n"
105 " is-not-null (yes|no) \"no\"\n"
106 " ordered (yes|no) \"no\"\n"
107 " >\n"
108
109 " <!ELEMENT relationship EMPTY>\n"
110 " <!ATTLIST relationship\n"
111 " name CDATA #REQUIRED\n"
112 " description CDATA \"\"\n"
113 " class-type CDATA #REQUIRED\n"
114 " low-cc (zero|one) #REQUIRED\n"
115 " high-cc (one|many) #REQUIRED\n"
116 " is-composite (yes|no) #REQUIRED\n"
117 " is-exclusive (yes|no) #REQUIRED\n"
118 " is-dependent (yes|no) #REQUIRED\n"
119 " ordered (yes|no) \"no\"\n"
120 " >\n"
121
122 " <!ELEMENT method (method-implementation*)>\n"
123 " <!ATTLIST method\n"
124 " name CDATA #REQUIRED\n"
125 " description CDATA \"\"\n"
126 " >\n"
127
128 " <!ELEMENT method-implementation EMPTY>\n"
129 " <!ATTLIST method-implementation\n"
130 " language CDATA #REQUIRED\n"
131 " prototype CDATA #REQUIRED\n"
132 " body CDATA \"\"\n"
133 " >\n"
134
135 "]>";
136
137const char OksFile::xml_data_file_dtd[] =
138 "<!DOCTYPE oks-data [\n"
139
140 " <!ELEMENT oks-data (info, (include)?, (comments)?, (obj)+)>\n"
141
142 " <!ELEMENT info EMPTY>\n"
143 " <!ATTLIST info\n"
144 " name CDATA #IMPLIED\n"
145 " type CDATA #IMPLIED\n"
146 " num-of-items CDATA #REQUIRED\n"
147 " oks-format CDATA #FIXED \"data\"\n"
148 " oks-version CDATA #REQUIRED\n"
149 " created-by CDATA #IMPLIED\n"
150 " created-on CDATA #IMPLIED\n"
151 " creation-time CDATA #IMPLIED\n"
152 " last-modified-by CDATA #IMPLIED\n"
153 " last-modified-on CDATA #IMPLIED\n"
154 " last-modification-time CDATA #IMPLIED\n"
155 " >\n"
156
157 " <!ELEMENT include (file)*>\n"
158 " <!ELEMENT file EMPTY>\n"
159 " <!ATTLIST file\n"
160 " path CDATA #REQUIRED\n"
161 " >\n"
162
163 " <!ELEMENT comments (comment)*>\n"
164 " <!ELEMENT comment EMPTY>\n"
165 " <!ATTLIST comment\n"
166 " creation-time CDATA #REQUIRED\n"
167 " created-by CDATA #REQUIRED\n"
168 " created-on CDATA #REQUIRED\n"
169 " author CDATA #REQUIRED\n"
170 " text CDATA #REQUIRED\n"
171 " >\n"
172
173 " <!ELEMENT obj (attr | rel)*>\n"
174 " <!ATTLIST obj\n"
175 " class CDATA #REQUIRED\n"
176 " id CDATA #REQUIRED\n"
177 " >\n"
178 " <!ELEMENT attr (data)*>\n"
179 " <!ATTLIST attr\n"
180 " name CDATA #REQUIRED\n"
181 " type (bool|s8|u8|s16|u16|s32|u32|s64|u64|float|double|date|time|string|uid|enum|class|-) \"-\"\n"
182 " val CDATA \"\"\n"
183 " >\n"
184 " <!ELEMENT data EMPTY>\n"
185 " <!ATTLIST data\n"
186 " val CDATA #REQUIRED\n"
187 " >\n"
188 " <!ELEMENT rel (ref)*>\n"
189 " <!ATTLIST rel\n"
190 " name CDATA #REQUIRED\n"
191 " class CDATA \"\"\n"
192 " id CDATA \"\"\n"
193 " >\n"
194 " <!ELEMENT ref EMPTY>\n"
195 " <!ATTLIST ref\n"
196 " class CDATA #REQUIRED\n"
197 " id CDATA #REQUIRED\n"
198 " >\n"
199 "]>";
200
201std::string
202FailedAddInclude::fill(const OksFile& file, const std::string& include_name, const std::string& reason) noexcept
203{
204 return (std::string("Failed to add include \'") + include_name + "\' to file \'" + file.get_full_file_name() +
205 "\' because:\n" + reason);
206}
207
208std::string
209FailedRemoveInclude::fill(const OksFile& file, const std::string& include_name, const std::string& reason) noexcept
210{
211 return (std::string("Failed to remove include \'") + include_name + "\' from file \'" + file.get_full_file_name() +
212 "\' because:\n" + reason);
213}
214
215std::string
217 const std::string& from,
218 const std::string& to,
219 const std::string& reason) noexcept
220{
221 return (std::string("Failed to rename include of \'") + file.get_full_file_name() + "\' from \'" + from + "\' to \'" +
222 to + "\' because:\n" + reason);
223}
224
225std::string
226FailedAddComment::fill(const OksFile& file, const std::string& reason) noexcept
227{
228 return (std::string("Failed to add new comment to file \'") + file.get_full_file_name() + "\' because:\n" + reason);
229}
230
231std::string
232FailedRemoveComment::fill(const OksFile& file, const std::string& creation_time, const std::string& reason) noexcept
233{
234 return (std::string("Failed to remove comment created at \'") + creation_time + "\' from file \'" +
235 file.get_full_file_name() + "\' because:\n" + reason);
236}
237
238std::string
239FailedChangeComment::fill(const OksFile& file, const std::string& creation_time, const std::string& reason) noexcept
240{
241 return (std::string("Failed to change comment created at \'") + creation_time + "\' from file \'" +
242 file.get_full_file_name() + "\' because:\n" + reason);
243}
244
245std::string
246FileLockError::fill(const OksFile& file, bool lock_action, const std::string& reason) noexcept
247{
248 return (std::string("Failed to ") + (lock_action ? "" : "un") + "lock file \'" + file.get_full_file_name() +
249 "\' because:\n" + reason);
250}
251
252std::string
253FileChangeError::fill(const OksFile& file, const std::string& action, const std::string& reason) noexcept
254{
255 return (std::string("Failed to ") + action + " of file \'" + file.get_full_file_name() + "\' because:\n" + reason);
256}
257
258std::string
259FileCompareError::fill(const std::string& src, const std::string& dest, const std::string& reason) noexcept
260{
261 return (std::string("Failed to compare file \'") + src + "\' with \'" + dest + "\' because:\n" + reason);
262}
263
264OksFile::OksFile(const std::string& s,
265 const std::string& ln,
266 const std::string& ft,
267 const std::string& ff,
268 OksKernel* k)
269 : p_short_name(s)
270 , p_full_name(s)
271 , p_logical_name(ln)
272 , p_type(ft)
273 , p_oks_format(ff)
275 , p_size(0)
276 , p_created_by(OksKernel::get_user_name())
277 , p_creation_time(boost::posix_time::second_clock::universal_time())
278 , p_created_on(OksKernel::get_host_name())
280 , p_lock()
281 , p_is_updated(false)
282 , p_is_read_only(true)
283 , p_last_modified(0)
285 , p_is_on_disk(false)
286 , p_included_by(0)
287 , p_kernel(k)
288{
293}
294
295void
297{
298 for (std::map<std::string, oks::Comment*>::iterator i = p_comments.begin(); i != p_comments.end(); ++i) {
299 delete i->second;
300 }
301
302 p_comments.clear();
303}
304
306{
308}
309
310OksFile&
312{
313 if (&f != this) {
316
317 p_short_name = f.p_short_name;
318 p_full_name = f.p_full_name;
319 // p_repository = f.p_repository;
320 p_repository_name = f.p_repository_name;
321 p_logical_name = f.p_logical_name;
322 p_type = f.p_type;
323 p_oks_format = f.p_oks_format;
324 p_number_of_items = f.p_number_of_items;
325 p_size = f.p_size;
326 p_created_by = f.p_created_by;
327 p_creation_time = f.p_creation_time;
328 p_created_on = f.p_created_on;
329 p_last_modified_by = f.p_last_modified_by;
330 p_last_modification_time = f.p_last_modification_time;
331 p_last_modified_on = f.p_last_modified_on;
332 p_open_mode = f.p_open_mode;
333 p_is_updated = f.p_is_updated;
334 p_lock = f.p_lock;
335 p_is_read_only = f.p_is_read_only;
336 p_lock_file_name = f.p_lock_file_name;
337 p_list_of_include_files = f.p_list_of_include_files;
338 p_last_modified = f.p_last_modified;
339 p_repository_last_modified = f.p_repository_last_modified;
340 p_is_on_disk = f.p_is_on_disk;
341 p_included_by = f.p_included_by;
342 p_kernel = f.p_kernel;
343
344 for (const auto& i : f.p_comments) {
345 p_comments[i.first] = new oks::Comment(*i.second);
346 }
347 }
348
349 return *this;
350}
351
352// read xml-file header from file
353
354const char _empty_str[] = "empty";
355
356OksFile::OksFile(std::shared_ptr<OksXmlInputStream> xmls, const std::string& sp, const std::string& fp, OksKernel* k)
357 : p_short_name(sp)
358 , p_full_name(fp)
359 , p_oks_format(_empty_str, sizeof(_empty_str) - 1)
360 , p_creation_time(boost::posix_time::not_a_date_time)
361 , p_last_modification_time(boost::posix_time::not_a_date_time)
362 , p_lock()
363 , p_is_updated(false)
364 , p_is_read_only(true)
365 , p_last_modified(0)
367 , p_is_on_disk(true)
368 , p_included_by(0)
369 , p_kernel(k)
370{
371 const char* fname = "OksFile::OksFile()";
372
373 // create_lock_name();
375
376 // check file header
377
378 try {
379
380 // skip an xml file header
381
382 {
383 const char* tag_start = xmls->get_tag_start();
384
385 if (!oks::cmp_str4(tag_start, "?xml")) {
386 xmls->throw_unexpected_tag(tag_start, "?xml");
387 }
388 }
389
390 // skip possible tag attributes
391
392 while (true) {
393 OksXmlAttribute attr(*xmls);
394
395 // check for close of tag
396
397 if (oks::cmp_str1(attr.name(), ">") || oks::cmp_str1(attr.name(), "/") || oks::cmp_str1(attr.name(), "?")) {
398 break;
399 }
400
401 // check for start of info tag
402
403 if (!oks::cmp_str7(attr.name(), "version") && !oks::cmp_str8(attr.name(), "encoding")) {
404 if (!p_kernel->get_silence_mode()) {
405 Oks::warning_msg(fname) << " Unexpected attribute \'" << attr.name()
406 << "\' in the xml file header. Either \'version\' or \'encoding\' is expected.\n";
407 }
408 }
409 }
410
411 } catch (oks::exception& e) {
412 throw oks::FailedRead("an xml file header", e);
413 } catch (std::exception& e) {
414 throw oks::FailedRead("an xml file header", e.what());
415 }
416
417 // skip document type declaration and comments
418
419 {
420 while (true) {
421 try {
422 const char* dtd = xmls->get_tag();
423 const char dtd_start[] = "<!DOCTYPE ";
424 if (!strncmp(dtd_start, dtd, sizeof(dtd_start) - 1)) {
425 break;
426 }
427 } catch (oks::exception& e) {
428 throw oks::FailedRead("DTD section", e);
429 } catch (std::exception& e) {
430 throw oks::FailedRead("DTD section", e.what());
431 }
432 }
433 }
434
435 // skip
436
437 try {
438 xmls->store_position();
439
440 const char* a_tag = xmls->get_tag();
441
442 const char xml_stylesheet_start[] = "<?xml-stylesheet";
443 if (strncmp(xml_stylesheet_start, a_tag, sizeof(xml_stylesheet_start) - 1)) {
444 xmls->restore_position();
445 }
446 } catch (oks::exception& e) {
447 throw oks::FailedRead("an xml-stylesheet tag or an oks tag", e);
448 } catch (std::exception& e) {
449 throw oks::FailedRead("an xml-stylesheet tag or an oks tag", e.what());
450 }
451
452 // read start-of-tag
453
454 try {
455 xmls->get_tag_start();
456 } catch (oks::exception& e) {
457 throw oks::FailedRead("tag", e);
458 } catch (std::exception& e) {
459 throw oks::FailedRead("tag", e.what());
460 }
461
462 // read info tag
463
464 try {
465 const char* tag_start = xmls->get_tag_start();
466
467 if (!oks::cmp_str4(tag_start, xml_info_tag)) {
468 xmls->throw_unexpected_tag(tag_start, xml_info_tag);
469 }
470 } catch (oks::exception& e) {
471 throw oks::FailedRead("<info> tag", e);
472 } catch (std::exception& e) {
473 throw oks::FailedRead("<info> tag", e.what());
474 }
475
476 std::string oks_version;
477
478 // read class attributes
479
480 try {
481 while (true) {
482 OksXmlAttribute attr(*xmls);
483
484 // check for close of tag
485
486 if (oks::cmp_str1(attr.name(), ">") || oks::cmp_str1(attr.name(), "/")) {
487 break;
488 }
489
490 // check for known info' attributes
491
492 else if (oks::cmp_str4(attr.name(), "name"))
493 p_logical_name.assign(attr.value(), attr.value_len());
494 else if (oks::cmp_str4(attr.name(), "type"))
495 p_type.assign(attr.value(), attr.value_len());
496 else if (oks::cmp_str10(attr.name(), "oks-format"))
497 p_oks_format.assign(attr.value(), attr.value_len());
498 else if (oks::cmp_str10(attr.name(), "created-by"))
499 p_created_by.assign(attr.value(), attr.value_len());
500 else if (oks::cmp_str10(attr.name(), "created-on"))
501 p_created_on.assign(attr.value(), attr.value_len());
502 else if (oks::cmp_str11(attr.name(), "oks-version"))
503 oks_version.assign(attr.value(), attr.value_len());
504 else if (oks::cmp_str12(attr.name(), "num-of-items"))
505 p_number_of_items = atol(attr.value());
506 else if (oks::cmp_str13(attr.name(), "creation-time"))
507 p_creation_time = oks::str2time(attr.value(), attr.value_len(), p_full_name.c_str());
508 else if (oks::cmp_str15(attr.name(), "num-of-includes"))
509 continue; // ignore this value
510 else if (oks::cmp_str16(attr.name(), "last-modified-by"))
511 p_last_modified_by.assign(attr.value(), attr.value_len());
512 else if (oks::cmp_str16(attr.name(), "last-modified-on"))
513 p_last_modified_on.assign(attr.value(), attr.value_len());
514 else if (!strcmp(attr.name(), "last-modification-time"))
516 else {
517 p_oks_format.clear();
518 xmls->throw_unexpected_tag(attr.name(), "info\'s tags");
519 }
520 }
521 } catch (oks::exception& e) {
522 throw oks::FailedRead("<info> tag attribute", e);
523 } catch (std::exception& e) {
524 throw oks::FailedRead("<info> tag attribute", e.what());
525 }
526
527 // read include and comments sections
528 while (true) {
529 xmls->store_position();
530
531 bool read_include = false;
532
533 try {
534 const char* tag_start = xmls->get_tag_start();
535 if (oks::cmp_str7(tag_start, xml_include_tag)) {
536 read_include = true;
537 } else if (oks::cmp_str8(tag_start, xml_comments_tag)) {
538 read_include = false;
539 } else {
540 xmls->restore_position();
541 return;
542 }
543 } catch (oks::exception& e) {
544 throw oks::FailedRead("a tag", e);
545 } catch (std::exception& e) {
546 throw oks::FailedRead("a tag", e.what());
547 }
548
549 if (read_include) {
550 while (true) {
551 try {
552
553 {
554 const char* tag_start = xmls->get_tag_start();
555 if (!oks::cmp_str4(tag_start, xml_file_tag)) {
556 if (!oks::cmp_str8(tag_start, "/include")) {
557 xmls->throw_unexpected_tag(tag_start + 1, xml_file_tag);
558 }
559 break;
560 }
561 }
562
563 while (true) {
564 OksXmlAttribute attr(*xmls);
565
566 // check for close of tag
567 if (oks::cmp_str1(attr.name(), ">") || oks::cmp_str1(attr.name(), "/")) {
568 break;
569 }
570
571 // check for known info' attributes
572 else if (oks::cmp_str4(attr.name(), "path"))
573 p_list_of_include_files.push_back(std::string(attr.value(), attr.value_len()));
574 else {
575 p_oks_format.clear();
576 xmls->throw_unexpected_tag(attr.name(), "path");
577 }
578 }
579
580 } catch (oks::exception& e) {
581 throw oks::FailedRead("<file> tag", e);
582 } catch (std::exception& e) {
583 throw oks::FailedRead("<file> tag", e.what());
584 }
585 }
586 } else {
587 while (true) {
588 try {
589
590 {
591 const char* tag_start = xmls->get_tag_start();
592 if (!oks::cmp_str7(tag_start, xml_comment_tag)) {
593 if (!oks::cmp_str9(tag_start, "/comments")) {
594 xmls->throw_unexpected_tag(tag_start, xml_comment_tag);
595 }
596 return;
597 }
598 }
599
600 std::unique_ptr<oks::Comment> comment(new oks::Comment());
601 std::string creation_time;
602
603 while (true) {
604 OksXmlAttribute attr(*xmls);
605
606 // check for close of tag
607 if (oks::cmp_str1(attr.name(), ">") || oks::cmp_str1(attr.name(), "/")) {
608 break;
609 }
610
611 // check for known info' attributes
612 else if (oks::cmp_str4(attr.name(), "text"))
613 comment->p_text.assign(attr.value(), attr.value_len());
614 else if (oks::cmp_str6(attr.name(), "author"))
615 comment->p_author.assign(attr.value(), attr.value_len());
616 else if (oks::cmp_str10(attr.name(), "created-by"))
617 comment->p_created_by.assign(attr.value(), attr.value_len());
618 else if (oks::cmp_str10(attr.name(), "created-on"))
619 comment->p_created_on.assign(attr.value(), attr.value_len());
620 else if (oks::cmp_str13(attr.name(), "creation-time"))
621 creation_time.assign(attr.value(), attr.value_len());
622 else {
623 p_oks_format.clear();
624 xmls->throw_unexpected_tag(attr.name(), "comment\'s tags");
625 }
626 }
627
628 comment->validate(creation_time);
629
630 if (p_comments.find(creation_time) != p_comments.end()) {
631 std::ostringstream text;
632 text << "The comment created at \'" << creation_time << "\' was already defined in this file";
633 throw std::runtime_error(text.str().c_str());
634 }
635
636 p_comments[creation_time] = comment.release();
637
638 } catch (oks::exception& e) {
639 throw oks::FailedRead("<comment>", e);
640 } catch (std::exception& e) {
641 throw oks::FailedRead("<comment>", e.what());
642 }
643 }
644 }
645 }
646}
647
648void
649oks::Comment::validate(const std::string& creation_time)
650{
651 // YYYYMMDDThhmmss
652 if (creation_time.size() != 15 || creation_time[8] != 'T') {
653 std::ostringstream msg;
654 msg << "the creation time \'" << creation_time << "\' is not an ISO-8601 date-time";
655 throw std::runtime_error(msg.str().c_str());
656 }
657
658 validate();
659}
660
661void
663{
664 if (p_text.empty()) {
665 throw std::runtime_error("text is empty");
666 }
667}
668
669oks::Comment::Comment(const std::string& text, const std::string& author)
670 : p_created_by(OksKernel::get_user_name())
671 , p_author(author)
672 , p_created_on(OksKernel::get_host_name())
673 , p_text(text)
674{
675 validate();
676}
677
679 : p_created_by(src.p_created_by)
680 , p_author(src.p_author)
681 , p_created_on(src.p_created_on)
682 , p_text(src.p_text)
683{
684}
685
686void
687OksFile::add_comment(const std::string& text, const std::string& author)
688{
689 try {
690 lock();
691 } catch (oks::exception& ex) {
692 throw oks::FailedAddComment(*this, ex);
693 }
694
695 boost::posix_time::ptime now = boost::posix_time::second_clock::universal_time();
696 std::string creation_time = boost::posix_time::to_iso_string(now);
697
698 try {
699 std::unique_ptr<oks::Comment> comment(new oks::Comment(text, author));
700 comment->validate();
701
702 oks::Comment*& x(p_comments[creation_time]);
703
704 if (x == 0) {
705 x = comment.release();
706 } else {
707 x->p_text += "\n-----\n";
708 x->p_text.append(text);
709 }
710 } catch (std::exception& ex) {
711 throw oks::FailedAddComment(*this, ex.what());
712 }
713
714 p_is_updated = true;
715}
716
718OksFile::get_comment(const std::string& creation_time) noexcept
719{
720 std::map<std::string, oks::Comment*>::const_iterator i = p_comments.find(creation_time);
721 return (i == p_comments.end()) ? 0 : i->second;
722}
723
724void
725OksFile::modify_comment(const std::string& creation_time, const std::string& text, const std::string& author)
726{
727 if (oks::Comment* comment = get_comment(creation_time)) {
728 try {
729 lock();
730 } catch (oks::exception& ex) {
731 throw oks::FailedChangeComment(*this, creation_time, ex);
732 }
733
734 std::string saved_author(comment->p_author);
735 std::string saved_text(comment->p_text);
736
737 comment->p_author = author;
738 comment->p_text = text;
739
740 try {
741 comment->validate();
742 } catch (std::exception& ex) {
743 comment->p_author = saved_author;
744 comment->p_text = saved_text;
745 throw oks::FailedChangeComment(*this, creation_time, ex.what());
746 }
747
748 p_is_updated = true;
749 } else {
750 throw oks::FailedChangeComment(*this, creation_time, "cannot find comment");
751 }
752}
753
754void
755OksFile::remove_comment(const std::string& creation_time)
756{
757 if (oks::Comment* comment = get_comment(creation_time)) {
758 try {
759 lock();
760 } catch (oks::exception& ex) {
761 throw oks::FailedRemoveComment(*this, creation_time, ex);
762 }
763
764 delete comment;
765 p_comments.erase(creation_time);
766 p_is_updated = true;
767 } else {
768 throw oks::FailedRemoveComment(*this, creation_time, "cannot find comment");
769 }
770}
771
772void
774{
775 const static std::string __data("data");
776 const static std::string __schema("schema");
777
778 try {
779 const char __oks_data[] = "oks-data";
780 const char __oks_schema[] = "oks-schema";
781
782 const char* id(__oks_data);
783 long id_len(sizeof(__oks_data) - 1);
784 const char* dtd(xml_data_file_dtd);
785 long dtd_len(sizeof(xml_data_file_dtd) - 1);
786
787 if (p_oks_format != __data) {
788 if (p_oks_format == __schema) {
789 id = __oks_schema;
790 id_len = sizeof(__oks_schema) - 1;
792 dtd_len = sizeof(xml_schema_file_dtd) - 1;
793 } else {
794 throw std::runtime_error("bad oks format");
795 }
796 }
797
798 {
799 const char __hdr_start[] = "\n\n<!-- ";
800 const char __hdr_end[] = " version 2.2 -->\n\n\n";
801
802 std::string header(xml_file_header, sizeof(xml_file_header) - 1);
803 header.append(__hdr_start, sizeof(__hdr_start) - 1);
804 header.append(id, id_len);
805 header.append(__hdr_end, sizeof(__hdr_end) - 1);
806 header.append(dtd, dtd_len);
807
808 xmls.put_raw(header.c_str(), header.size());
809 xmls.put_raw('\n');
810 xmls.put_raw('\n');
811 }
812
813 xmls.put_start_tag(id, id_len);
814
815 xmls.put_raw('>');
816 xmls.put_raw('\n');
817 xmls.put_raw('\n');
818
819 // "creation-time" may not be filled
820
821 std::string created_c_str;
822 if (!p_creation_time.is_not_a_date_time()) {
823 created_c_str = boost::posix_time::to_iso_string(p_creation_time);
824 }
825
826 // get last-modified information
827
828 if (p_repository_name.empty()) {
829 p_last_modification_time = boost::posix_time::second_clock::universal_time();
832 }
833
834 std::string last_modified_c_str = boost::posix_time::to_iso_string(p_last_modification_time);
835
836 xmls.put_start_tag(xml_info_tag, sizeof(xml_info_tag) - 1);
837 xmls.put_attribute("name", sizeof("name") - 1, p_logical_name.c_str());
838 xmls.put_attribute("type", sizeof("type") - 1, p_type.c_str());
839 xmls.put_attribute("num-of-items", sizeof("num-of-items") - 1, p_number_of_items);
840 xmls.put_attribute("oks-format", sizeof("oks-format") - 1, p_oks_format.c_str());
841 xmls.put_attribute("oks-version", sizeof("oks-version") - 1, OksKernel::GetVersion());
842 xmls.put_attribute("created-by", sizeof("created-by") - 1, p_created_by.c_str());
843 xmls.put_attribute("created-on", sizeof("created-on") - 1, p_created_on.c_str());
844 if (!created_c_str.empty())
845 xmls.put_attribute("creation-time", sizeof("creation-time") - 1, created_c_str.c_str());
846 if (p_repository_name.empty()) {
847 xmls.put_attribute("last-modified-by", sizeof("last-modified-by") - 1, p_last_modified_by.c_str());
848 xmls.put_attribute("last-modified-on", sizeof("last-modified-on") - 1, p_last_modified_on.c_str());
849 xmls.put_attribute("last-modification-time", sizeof("last-modification-time") - 1, last_modified_c_str.c_str());
850 }
851 xmls.put_end_tag();
852
853 if (!p_list_of_include_files.empty()) {
854 xmls.put_raw('\n');
856
857 xmls.put_raw('>');
858 xmls.put_raw('\n');
859
860 for (const auto& i : p_list_of_include_files) {
861 xmls.put_raw(' ');
862 xmls.put_start_tag(xml_file_tag, sizeof(xml_file_tag) - 1);
863 xmls.put_attribute("path", sizeof("path") - 1, i.c_str());
864 xmls.put_end_tag();
865 }
866
868 xmls.put_raw('\n');
869 }
870
871 if (!p_comments.empty()) {
873
874 xmls.put_raw('>');
875 xmls.put_raw('\n');
876
877 for (const auto& i : p_comments) {
878 xmls.put_raw(' ');
880 xmls.put_attribute("creation-time", sizeof("creation-time") - 1, i.first.c_str());
881 xmls.put_attribute("created-by", sizeof("created-by") - 1, i.second->p_created_by.c_str());
882 xmls.put_attribute("created-on", sizeof("created-on") - 1, i.second->p_created_on.c_str());
883 xmls.put_attribute("author", sizeof("author") - 1, i.second->p_author.c_str());
884 xmls.put_attribute("text", sizeof("text") - 1, i.second->p_text.c_str());
885 xmls.put_end_tag();
886 }
887
889 xmls.put_raw('\n');
890 }
891
892 xmls.put_raw('\n');
893 } catch (std::exception& ex) {
894 throw oks::FailedSave("oks-file", p_full_name, ex.what());
895 }
896
897 p_is_on_disk = true;
898}
899
900bool
902{
903 return (!p_kernel->get_user_repository_root().empty());
904}
905
906void
908{
909 // if(size_t len = OksKernel::get_repository_root().size()) {
910 // if(p_full_name.size() > len && p_full_name.substr(0, len) == OksKernel::get_repository_root()) {
911 // p_repository = GlobalRepository;
912 // p_repository_name = p_full_name.substr(len + 1);
913 // TLOG_DEBUG( 3 ) << "file \'" << p_full_name << "\' comes from user repository [\'" << p_repository_name <<
914 // "\']"; return;
915 // }
916 // }
917
918 const std::string& s(p_kernel->get_user_repository_root());
919 if (size_t len = s.size()) {
920 if (p_full_name.size() > len && p_full_name.substr(0, len) == s) {
921 // p_repository = UserRepository;
922 p_repository_name = p_full_name.substr(len + 1);
923
924 TLOG_DEBUG(3) << "file \'" << p_full_name << "\' comes from user repository [\'" << p_repository_name << "\']";
925 return;
926
927 // std::string repository_file = OksKernel::get_repository_root() + '/' + p_repository_name;
928 //
929 // struct stat buf;
930 // if(stat(repository_file.c_str(), &buf) == 0) {
931 // TLOG_DEBUG( 3 ) << "file \'" << p_full_name << "\' comes from user repository [\'" << p_repository_name
932 // << "\']" ; return;
933 // }
934 // else {
935 // TLOG_DEBUG( 3 ) << "file \'" << p_full_name << "\' is found in user repository [\'" << p_repository_name
936 // << "\'] but does not exist in global one [\'" << OksKernel::get_repository_root() << "\']" ;
937 // }
938 }
939 }
940
941 TLOG_DEBUG(3) << "file \'" << p_full_name << "\' is not in a repository";
942 // p_repository = NoneRepository;
943 p_repository_name.clear();
944}
945
946void
948{
950
951 std::string::size_type idx = p_lock_file_name.find_last_of('/');
952 if (idx == std::string::npos)
953 p_lock_file_name = "./";
954 else
955 p_lock_file_name.erase(idx + 1);
956
957 const char _prefix_str[] = ".oks-lock-";
958 p_lock_file_name.append(_prefix_str, sizeof(_prefix_str) - 1);
959
960 idx = p_full_name.find_last_of('/');
961 std::string::size_type len(p_full_name.size());
962 if (idx == std::string::npos) {
963 idx = 0;
964 } else {
965 idx++;
966 len -= idx;
967 }
968
969 p_lock_file_name.append(p_full_name, idx, len);
970 p_lock_file_name.append(".txt");
971}
972
973// return true if lock exists and false if does not exist
974// the string is non-empty, if the lock file was read
975
976bool
977OksFile::get_lock_string(std::string& lock_file_contents) const
978{
980
981 lock_file_contents.clear();
982
983 const char* lock_name = p_lock_file_name.c_str();
984 struct stat buf;
985
986 if (stat(lock_name, &buf) == 0) {
987 std::ifstream f(lock_name);
988
989 if (f.good()) {
990 std::getline(f, lock_file_contents);
991 return true;
992 } else {
993 lock_file_contents = "unknown [cannot read lock file \'";
994 lock_file_contents += p_lock_file_name;
995 lock_file_contents += "\']";
996 return true;
997 }
998 }
999
1000 return false;
1001}
1002
1003void
1005{
1006 if (p_nolock_mode) {
1007 // Nasty hack to allow code generation on the fly without locking
1008 // file. Just return without locking!
1009 return;
1010 }
1011
1013
1014 if (p_lock != nullptr) {
1015 return;
1016 }
1017
1018 // check that the file is not read-only
1019
1020 {
1021 struct stat buf;
1022
1023 if (stat(p_full_name.c_str(), &buf) == 0) {
1024 if (OksKernel::check_read_only(this) == true) {
1025 throw oks::FileLockError(*this, true, "file is read-only");
1026 }
1027 }
1028 }
1029
1030 // check lock and report problem if it exists and cannot be reset
1031
1032 {
1033 std::string lock_file_contents;
1034
1035 if (get_lock_string(lock_file_contents)) {
1036 try {
1037 boost::interprocess::file_lock lock(p_lock_file_name.c_str());
1038
1039 if (lock.try_lock() == false) {
1040 std::ostringstream text;
1041 text << "file is already locked by \"" << lock_file_contents << '\"';
1042 throw oks::FileLockError(*this, true, text.str());
1043 } else {
1044 try {
1045 lock.unlock();
1046 } catch (const boost::interprocess::interprocess_exception& ex) {
1047 std::ostringstream text;
1048 text << "boost::interprocess::unlock() failed: \"" << ex.what() << '\"';
1049 throw oks::FileLockError(*this, false, text.str());
1050 }
1051
1052 if (!p_kernel->get_silence_mode()) {
1053 Oks::warning_msg("OksFile::lock()") << "Remove obsolete lock of file \'" << p_full_name
1054 << "\' created by \n\"" << lock_file_contents << "\"\n";
1055 }
1056
1057 if (unlink(p_lock_file_name.c_str()) != 0) {
1058 std::ostringstream text;
1059 text << "failed to remove lock file \'" << p_lock_file_name << "\':\n" << oks::strerror(errno);
1060 throw oks::FileLockError(*this, false, text.str());
1061 }
1062 }
1063 } catch (const boost::interprocess::interprocess_exception& ex) {
1064 std::ostringstream text;
1065 text << "boost::interprocess::try_lock() failed: \"" << ex.what() << '\"';
1066 throw oks::FileLockError(*this, false, text.str());
1067 }
1068 }
1069 }
1070
1071 // write lock file
1072
1073 {
1074 std::ofstream f(p_lock_file_name.c_str());
1075
1076 if (!f.good()) {
1077 std::ostringstream text;
1078 text << "failed to create lock file \'" << p_lock_file_name << '\'';
1079 throw oks::FileLockError(*this, true, text.str());
1080 }
1081
1082 try {
1083 boost::posix_time::ptime now(boost::posix_time::second_clock::universal_time());
1084 f << "process " << getpid() << " on " << OksKernel::get_host_name() << " started by "
1085 << OksKernel::get_user_name() << " at " << boost::posix_time::to_simple_string(now) << " (UTC)" << std::endl;
1086 f.flush();
1087 f.close();
1088 } catch (std::exception& ex) {
1089 std::ostringstream text;
1090 text << "failed to write lock file \'" << p_lock_file_name << "\': " << ex.what();
1091 throw oks::FileLockError(*this, true, text.str());
1092 }
1093 }
1094
1095 try {
1096 p_lock.reset(new boost::interprocess::file_lock(p_lock_file_name.c_str()));
1097
1098 if (p_lock->try_lock() == false) {
1099 throw std::runtime_error("file is locked by another process");
1100 }
1101 } catch (const std::exception& ex) {
1102 std::ostringstream text;
1103 text << "boost::interprocess::try_lock() failed: \"" << ex.what() << '\"';
1104 p_lock.reset();
1105 throw oks::FileLockError(*this, false, text.str());
1106 }
1107}
1108
1109void
1111{
1112 if (p_lock == nullptr)
1113 return;
1114
1115 try {
1116 p_lock->unlock();
1117 } catch (const boost::interprocess::interprocess_exception& ex) {
1118 std::ostringstream text;
1119 text << "boost::interprocess::unlock() failed: \"" << ex.what() << '\"';
1120 p_lock.reset();
1121 throw oks::FileLockError(*this, false, text.str());
1122 }
1123
1124 p_lock.reset();
1125
1126 if (unlink(p_lock_file_name.c_str()) != 0 && errno != ENOENT) {
1127 std::ostringstream text;
1128 text << "failed to remove lock file \'" << p_lock_file_name << "\':\n" << oks::strerror(errno);
1129 throw oks::FileLockError(*this, false, text.str());
1130 }
1131}
1132
1133std::list<std::string>::iterator
1134OksFile::find_include_file(const std::string& s)
1135{
1136 std::list<std::string>::iterator i = p_list_of_include_files.begin();
1137
1138 for (; i != p_list_of_include_files.end(); ++i) {
1139 if (*i == s)
1140 break;
1141 }
1142
1143 return i;
1144}
1145
1146OksFile*
1148{
1149 if (p_included_by == 0 && parent_h != 0) {
1150 p_included_by = parent_h;
1151 }
1152
1153 return this;
1154}
1155
1156void
1157OksFile::add_include_file(const std::string& s)
1158{
1159 // check if the file was already included
1161 return;
1162 }
1163
1164 // lock file
1165 try {
1166 lock();
1167 } catch (oks::exception& ex) {
1168 throw oks::FailedAddInclude(*this, s, ex);
1169 }
1170
1171 // try to find path to include and load it
1172 try {
1173 std::string path = p_kernel->get_file_path(s, this);
1174 p_kernel->k_load_file(path, true, this, 0);
1175 } catch (std::exception& ex) {
1176 throw oks::FailedAddInclude(*this, s, ex.what());
1177 }
1178
1179 // add include and mark file as updated
1180 p_list_of_include_files.push_back(s);
1181 p_is_updated = true;
1182}
1183
1184void
1185OksFile::remove_include_file(const std::string& s)
1186{
1187 // search included file
1188 std::list<std::string>::iterator i = find_include_file(s);
1189
1190 // check if the file was included
1191 if (i == p_list_of_include_files.end()) {
1192 throw oks::FailedRemoveInclude(*this, s, "there is no such include file");
1193 }
1194
1195 // lock file
1196 try {
1197 lock();
1198 } catch (oks::exception& ex) {
1199 throw oks::FailedRemoveInclude(*this, s, ex);
1200 }
1201
1202 // remove include and mark file as updated
1203 p_list_of_include_files.erase(i);
1204 p_is_updated = true;
1205
1206 // close file, if it is not referenced by others
1208}
1209
1210void
1211OksFile::rename_include_file(const std::string& old_s, const std::string& new_s)
1212{
1213 if (old_s == new_s)
1214 return;
1215
1216 std::list<std::string>::iterator i1 = find_include_file(old_s);
1217 std::list<std::string>::iterator i2 = find_include_file(new_s);
1218
1219 if (i1 == p_list_of_include_files.end()) {
1220 throw oks::FailedRenameInclude(*this, old_s, new_s, "there is no such include file");
1221 }
1222
1223 if (i2 != p_list_of_include_files.end()) {
1224 throw oks::FailedRenameInclude(*this, old_s, new_s, "file with new name is already included");
1225 }
1226
1227 try {
1228 lock();
1229 } catch (oks::exception& ex) {
1230 throw oks::FailedRenameInclude(*this, old_s, new_s, ex);
1231 }
1232
1233 (*i1) = new_s;
1234 p_is_updated = true;
1235}
1236
1237void
1238OksFile::set_logical_name(const std::string& s)
1239{
1240 if (s == p_logical_name)
1241 return;
1242
1243 try {
1244 lock();
1245 } catch (oks::exception& ex) {
1246 throw oks::FileChangeError(*this, "set logical name", ex);
1247 }
1248
1249 p_logical_name = s;
1250 p_is_updated = true;
1251}
1252
1253void
1254OksFile::set_type(const std::string& s)
1255{
1256 if (s == p_type)
1257 return;
1258
1259 try {
1260 lock();
1261 } catch (oks::exception& ex) {
1262 throw oks::FileChangeError(*this, "set type", ex);
1263 }
1264
1265 p_type = s;
1266 p_is_updated = true;
1267}
1268
1269std::ostream&
1270operator<<(std::ostream& s, const oks::Comment& c)
1271{
1272 s << "user \"" << c.get_created_by() << "\" (" << c.get_author() << ")"
1273 << " on \"" << c.get_created_on() << "\" wrote: \"" << c.get_text() << "\"";
1274
1275 return s;
1276}
1277
1278std::ostream&
1279operator<<(std::ostream& s, const OksFile& f)
1280{
1281 s << "OKS file\n"
1282 " short file name: \'"
1283 << f.get_short_file_name()
1284 << "\'\n"
1285 " full file name: \'"
1286 << f.get_full_file_name()
1287 << "\'\n"
1288 " lock file name: \'"
1289 << f.get_lock_file()
1290 << "\'\n"
1291 " logical name: \'"
1292 << f.get_logical_name()
1293 << "\'\n"
1294 " type: \'"
1295 << f.get_type()
1296 << "\'\n"
1297 " oks format: \'"
1298 << f.get_oks_format()
1299 << "\'\n"
1300 " number of items: "
1301 << f.get_number_of_items()
1302 << "\n"
1303 " created by: "
1304 << f.get_created_by()
1305 << "\n"
1306 " creation time: "
1307 << boost::posix_time::to_simple_string(f.get_creation_time())
1308 << "\n"
1309 " created on: "
1310 << f.get_created_on()
1311 << "\n"
1312 " last modified by: \'"
1313 << f.get_last_modified_by()
1314 << "\'\n"
1315 " last modification time: "
1316 << boost::posix_time::to_simple_string(f.get_last_modification_time())
1317 << "\'\n"
1318 " last modified on: "
1319 << f.get_last_modified_on()
1320 << "\'\n"
1321 " is "
1322 << (f.is_read_only() ? "read-only" : "read-write")
1323 << "\n"
1324 " is "
1325 << (f.is_locked() ? "" : "not ")
1326 << "locked\n"
1327 " is "
1328 << (f.is_updated() ? "" : "not ") << "updated\n";
1329
1330 {
1331 size_t num_of_includes = f.get_include_files().size();
1332
1333 if (num_of_includes) {
1334 s << " contains " << num_of_includes << " include file(s)";
1335 for (const auto& i : f.get_include_files())
1336 s << " - \'" << i << "\'\n";
1337 } else {
1338 s << " contains no include files\n";
1339 }
1340 }
1341
1342 {
1343 size_t num_of_comments = f.get_comments().size();
1344
1345 if (num_of_comments) {
1346 s << " contains " << num_of_comments << " comment(s)";
1347 for (const auto& i : f.get_comments())
1348 s << " - " << boost::posix_time::to_simple_string(boost::posix_time::from_iso_string(i.first)) << ": \'"
1349 << *i.second << "\'\n";
1350 } else {
1351 s << " contains no comments\n";
1352 }
1353 }
1354
1355 s << "END of oks file\n";
1356
1357 return s;
1358}
1359
1360std::string
1362{
1363 std::string name;
1364
1365 if (!OksKernel::get_repository_root().empty()) {
1367 }
1368
1369 return name;
1370}
1371
1372void
1373OksFile::update_status_of_file(bool update_local, bool update_repository)
1374{
1375 struct stat buf;
1376
1377 if (update_local == true && p_is_on_disk == true) {
1378
1379 if (stat(p_full_name.c_str(), &buf) == 0) {
1380 p_last_modified = buf.st_mtime;
1381 }
1382 }
1383
1384 if (update_repository == true /*&& get_repository() == UserRepository*/) {
1385 std::string full_repository_name = make_repository_name();
1386
1387 if (!full_repository_name.empty() && stat(full_repository_name.c_str(), &buf) == 0) {
1388 p_repository_last_modified = buf.st_mtime;
1389 }
1390 }
1391}
1392
1395{
1396 if (p_is_on_disk == false) {
1397 return FileWasNotSaved;
1398 } else {
1399 struct stat buf;
1400
1401 if (stat(p_full_name.c_str(), &buf) != 0) {
1402 return FileRemoved;
1403 }
1404
1405 if (buf.st_mtime != p_last_modified) {
1406 return FileModified;
1407 }
1408
1409 // if(get_repository() == UserRepository) {
1410 // std::string full_repository_name = make_repository_name();
1411 //
1412 // if(!full_repository_name.empty()) {
1413 // if(stat(full_repository_name.c_str(), &buf) != 0) {
1414 // return FileRepositoryRemoved;
1415 // }
1416 //
1417 // if(buf.st_mtime != p_repository_last_modified) {
1418 // return FileRepositoryModified;
1419 // }
1420 // }
1421 // }
1422 }
1423
1424 return FileNotModified;
1425}
1426
1427void
1428OksFile::rename(const std::string& short_name, const std::string& full_name)
1429{
1430 p_short_name = short_name;
1431 p_full_name = full_name;
1434}
1435
1436void
1437OksFile::rename(const std::string& full_name)
1438{
1439 p_full_name = full_name;
1442}
1443
1444void
1445OksFile::get_all_include_files(const OksKernel* kernel, std::set<OksFile*>& out)
1446{
1447 const OksFile::Map& schema_files = kernel->schema_files();
1448 const OksFile::Map& data_files = kernel->data_files();
1449
1450 for (std::list<std::string>::iterator i = p_list_of_include_files.begin(); i != p_list_of_include_files.end(); ++i) {
1451 std::string s = kernel->get_file_path(*i, this);
1452 if (s.size()) {
1453 OksFile::Map::const_iterator j = data_files.find(&s);
1454 if (j != data_files.end()) {
1455 if (out.find(j->second) != out.end()) {
1456 continue;
1457 }
1458 out.insert(j->second);
1459 } else {
1460 j = schema_files.find(&s);
1461 if (j != schema_files.end()) {
1462 if (out.find(j->second) != out.end()) {
1463 continue;
1464 }
1465 out.insert(j->second);
1466 } else {
1467 continue;
1468 }
1469 }
1470
1471 j->second->get_all_include_files(kernel, out);
1472 }
1473 }
1474}
1475
1476// return true if the string is not info line:
1477// <info ... last-modification-time="nnnnnnnnTnnnnnn"/>
1478
1479static bool
1480is_not_info(const std::string& line)
1481{
1482 static const char start_tag[] = "<info ";
1483 static const char last_tag[] =
1484 "last-modification-time=\"yyyymmddThhmmss\"/>"; // 24 - is a position of first double quote
1485
1486 const std::string::size_type len = line.length();
1487
1488 return ((len < (sizeof(start_tag) + sizeof(last_tag))) ||
1489 (line.compare(0, sizeof(start_tag) - 1, start_tag, sizeof(start_tag) - 1) != 0) ||
1490 (line.compare(len - sizeof(last_tag) + 1, 24, last_tag, 24) != 0));
1491}
1492
1493bool
1494OksFile::compare(const char* file1_name, const char* file2_name)
1495{
1496 std::ifstream f1(file1_name);
1497 std::ifstream f2(file2_name);
1498
1499 if (!f1) {
1500 throw oks::FileCompareError(file1_name, file2_name, "cannot open file");
1501 }
1502
1503 if (!f2) {
1504 throw oks::FileCompareError(file2_name, file1_name, "cannot open file");
1505 }
1506
1507 std::string line1;
1508 std::string line2;
1509
1510 while (true) {
1511 if (f1.eof() && f2.eof()) {
1512 return true;
1513 }
1514
1515 std::getline(f1, line1);
1516 std::getline(f2, line2);
1517
1518 if ((line1 != line2) && (is_not_info(line1) || is_not_info(line2))) {
1519 return false;
1520 }
1521 }
1522
1523 return true;
1524}
1525
1526} // namespace oks
1527} // namespace dunedaq
The comment about file modification. A comment can be added when user saves file using OKS tools.
Definition file.hpp:294
std::string p_created_by
Definition file.hpp:329
Comment() noexcept
Definition file.hpp:300
std::string p_created_on
Definition file.hpp:331
std::string p_text
Definition file.hpp:332
std::string p_author
Definition file.hpp:330
Cannot add comment. Such exception is thrown when OKS cannot add new comment.
Definition file.hpp:213
static std::string fill(const OksFile &file, const std::string &reason) noexcept
Definition file.cpp:226
Cannot add include file. Such exception is thrown when OKS cannot add include file.
Definition file.hpp:123
static std::string fill(const OksFile &file, const std::string &include_name, const std::string &reason) noexcept
Definition file.cpp:202
Cannot change comment. Such exception is thrown when OKS cannot change comment.
Definition file.hpp:267
static std::string fill(const OksFile &file, const std::string &creation_time, const std::string &reason) noexcept
Definition file.cpp:239
Cannot remove comment. Such exception is thrown when OKS cannot remove comment.
Definition file.hpp:240
static std::string fill(const OksFile &file, const std::string &creation_time, const std::string &reason) noexcept
Definition file.cpp:232
Cannot remove include file. Such exception is thrown when OKS cannot remove include file.
Definition file.hpp:150
static std::string fill(const OksFile &file, const std::string &include_name, const std::string &reason) noexcept
Definition file.cpp:209
Cannot rename include file. Such exception is thrown when OKS cannot rename include file.
Definition file.hpp:177
static std::string fill(const OksFile &file, const std::string &from, const std::string &to, const std::string &reason) noexcept
Definition file.cpp:216
static std::string fill(const OksFile &file, const std::string &action, const std::string &reason) noexcept
Definition file.cpp:253
static std::string fill(const std::string &src, const std::string &dest, const std::string &reason) noexcept
Definition file.cpp:259
Cannot add include file. Such exception is thrown when OKS cannot add include file.
Definition file.hpp:51
static std::string fill(const OksFile &file, bool lock_action, const std::string &reason) noexcept
Definition file.cpp:246
Provides interface to the OKS XML schema and data files.
Definition file.hpp:355
static bool compare(const char *file1_name, const char *file2_name)
Compare two files.
Definition file.cpp:1494
static const char xml_schema_file_dtd[]
Definition file.hpp:750
std::shared_ptr< boost::interprocess::file_lock > p_lock
Definition file.hpp:737
std::string p_lock_file_name
Definition file.hpp:738
std::list< std::string >::iterator find_include_file(const std::string &)
Definition file.cpp:1134
std::string p_oks_format
Definition file.hpp:727
static const char xml_comments_tag[]
Definition file.hpp:755
std::map< std::string, oks::Comment * > p_comments
Definition file.hpp:744
void unlock()
Unlock OKS file.
Definition file.cpp:1110
void add_include_file(const std::string &name)
Add include file.
Definition file.cpp:1157
time_t p_repository_last_modified
Definition file.hpp:743
OksFile(const std::string &, const std::string &, const std::string &, const std::string &, OksKernel *)
Definition file.cpp:264
oks::Comment * get_comment(const std::string &creation_time) noexcept
Definition file.cpp:718
void get_all_include_files(const OksKernel *kernel, std::set< OksFile * > &out)
Get all include files.
Definition file.cpp:1445
void lock()
Lock OKS file.
Definition file.cpp:1004
void write(OksXmlOutputStream &)
Definition file.cpp:773
std::string p_created_by
Definition file.hpp:730
void set_type(const std::string &type)
Set file type.
Definition file.cpp:1254
void init_lock_name() const
Definition file.hpp:778
bool get_lock_string(std::string &info) const
Return lock status of OKS file and if the file is locked, get information string about process which ...
Definition file.cpp:977
static const char xml_data_file_dtd[]
Definition file.hpp:751
std::string make_repository_name() const
Definition file.cpp:1361
std::string p_short_name
Definition file.hpp:722
static bool p_nolock_mode
Definition file.hpp:720
boost::posix_time::ptime p_last_modification_time
Definition file.hpp:734
std::list< std::string > p_list_of_include_files
Definition file.hpp:741
boost::posix_time::ptime p_creation_time
Definition file.hpp:731
std::string p_logical_name
Definition file.hpp:725
const std::string & get_repository_name() const
Get name of file inside repository.
Definition file.hpp:553
void remove_comment(const std::string &creation_time)
Modify existing comment.
Definition file.cpp:755
void set_logical_name(const std::string &name)
Set logical name of file.
Definition file.cpp:1238
std::string p_repository_name
Definition file.hpp:724
std::string p_last_modified_by
Definition file.hpp:733
friend class OksKernel
Definition file.hpp:357
OksKernel * p_kernel
Definition file.hpp:747
void add_comment(const std::string &text, const std::string &author)
Add new comment to file.
Definition file.cpp:687
std::map< const std::string *, OksFile *, SortByName > Map
Definition file.hpp:382
void update_status_of_file(bool update_local=true, bool update_repository=true)
Update status of file.
Definition file.cpp:1373
std::string p_full_name
Definition file.hpp:723
std::string p_type
Definition file.hpp:726
bool is_repository_file() const
Get information about repository, the file belongs to.
Definition file.cpp:901
~OksFile() noexcept
Definition file.cpp:305
void create_lock_name()
Definition file.cpp:947
void check_repository()
Definition file.cpp:907
void clear_comments() noexcept
Definition file.cpp:296
static const char xml_file_tag[]
Definition file.hpp:754
OksFile * check_parent(const OksFile *parent_h)
Set given parent, if this file is not yet included.
Definition file.cpp:1147
const OksFile * p_included_by
Definition file.hpp:746
static const char xml_comment_tag[]
Definition file.hpp:756
std::string p_last_modified_on
Definition file.hpp:735
OksFile & operator=(const OksFile &)
Definition file.cpp:311
void modify_comment(const std::string &creation_time, const std::string &text, const std::string &author)
Definition file.cpp:725
void rename_include_file(const std::string &from, const std::string &to)
Rename include file.
Definition file.cpp:1211
static const char xml_file_header[]
Definition file.hpp:749
std::string p_created_on
Definition file.hpp:732
FileStatus get_status_of_file() const
Return update status of file.
Definition file.cpp:1394
static const char xml_include_tag[]
Definition file.hpp:753
void rename(const std::string &short_name, const std::string &full_name)
Definition file.cpp:1428
void remove_include_file(const std::string &name)
Remove include file.
Definition file.cpp:1185
static const char xml_info_tag[]
Definition file.hpp:752
Provides interface to the OKS kernel.
Definition kernel.hpp:615
const std::string & get_user_repository_root() const
Get user OKS repository root.
Definition kernel.cpp:335
static std::string & get_host_name()
Get hostname of given process.
Definition kernel.cpp:392
static std::string & get_user_name()
Get username of given process.
Definition kernel.cpp:427
static bool check_read_only(OksFile *f)
Check if the OKS file is read-only.
Definition kernel.cpp:1394
const OksFile::Map & data_files() const
Get all data files.
Definition kernel.hpp:1472
void k_close_dangling_includes()
Close files which lost their parent.
Definition kernel.cpp:1800
OksFile * k_load_file(const std::string &name, bool bind, const OksFile *parent, OksPipeline *pipeline)
Definition kernel.cpp:1634
std::string get_file_path(const std::string &path, const OksFile *parent_file=0, bool strict_paths=true) const
Calculates full path to file.
Definition kernel.cpp:1516
static const std::string & get_repository_root()
Get OKS repository root.
Definition kernel.cpp:280
static const char * GetVersion()
Get OKS version. The method returns string containing CVS tag and date of OKS build.
Definition kernel.cpp:274
bool get_silence_mode() const
Get status of silence mode. The method returns true, if the silence mode is switched 'On'....
Definition kernel.hpp:719
const OksFile::Map & schema_files() const
Get all schema files.
Definition kernel.hpp:1211
void put_last_tag(const char *, size_t len)
Definition xml.cpp:215
void put_attribute(const char *, size_t len, const char *)
Definition xml.cpp:230
void put_start_tag(const char *, size_t len)
Definition xml.cpp:184
static std::ostream & warning_msg(const char *)
Definition kernel.cpp:518
virtual const char * what() const noexcept
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:116
bool cmp_str8(const char *s1, const char s2[9])
Definition cstring.hpp:93
const std::string strerror(int error)
Convert C error number to string.
Definition kernel.cpp:111
bool cmp_str1(const char *s1, const char s2[2])
Definition cstring.hpp:15
bool cmp_str4(const char *s1, const char s2[5])
Definition cstring.hpp:45
bool cmp_str6(const char *s1, const char s2[7])
Definition cstring.hpp:69
bool cmp_str10(const char *s1, const char s2[11])
Definition cstring.hpp:111
static bool is_not_info(const std::string &line)
Definition file.cpp:1480
bool cmp_str9(const char *s1, const char s2[10])
Definition cstring.hpp:105
boost::posix_time::ptime str2time(const char *value, size_t len, const char *file_name=nullptr)
const char _empty_str[]
Definition file.cpp:354
std::ostream & operator<<(std::ostream &s, const oks::exception &ex)
bool cmp_str13(const char *s1, const char s2[14])
Definition cstring.hpp:129
bool cmp_str16(const char *s1, const char s2[17])
Definition cstring.hpp:147
bool cmp_str15(const char *s1, const char s2[16])
Definition cstring.hpp:141
bool cmp_str11(const char *s1, const char s2[12])
Definition cstring.hpp:117
bool cmp_str12(const char *s1, const char s2[13])
Definition cstring.hpp:123
bool cmp_str7(const char *s1, const char s2[8])
Definition cstring.hpp:81
The DUNE-DAQ namespace.
FELIX Initialization std::string initerror FELIX queue timed out
Both frame_count_limit and tp_count_limit were set to(disabled) in the TPCRawDataProcessor " "config. TPs will not send."
Definition ral.hpp:59
size_t value_len() const
Definition xml.hpp:288