Flow123d  last_with_con_2.0.0-4-g42e6930
type_output.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file type_output.cc
15  * @brief
16  */
17 
18 #include "input/type_output.hh"
19 #include "input/type_repository.hh"
20 #include "input/type_generic.hh"
21 #include "input/type_tuple.hh"
22 #include "system/system.hh"
23 #include <boost/algorithm/string/replace.hpp>
24 #include <boost/iostreams/filtering_stream.hpp>
25 #include <boost/iostreams/concepts.hpp>
26 #include <boost/iostreams/operations.hpp> // put
27 
28 
29 #include <string>
30 #include <limits>
31 #include <boost/regex.hpp>
32 
33 namespace Input {
34 namespace Type {
35 
36 using namespace std;
37 
38 
39 /*******************************************************************
40  * implementation of OutputBase
41  */
42 
44 
45 
46 
48 {
50 }
51 
52 
53 
54 void OutputBase::get_integer_bounds(Integer integer, int &lower , int &upper ) {
55  lower = integer.lower_bound_;
56  upper = integer.upper_bound_;
57 }
58 
59 
60 
61 void OutputBase::get_double_bounds(Double dbl, double &lower , double &upper ) {
62  lower = dbl.lower_bound_;
63  upper = dbl.upper_bound_;
64 }
65 
66 
67 
68 void OutputBase::get_array_sizes(Array array, unsigned int &lower , unsigned int &upper ) {
69  lower = array.data_->lower_bound_;
70  upper = array.data_->upper_bound_;
71 }
72 
73 
74 
75 void OutputBase::get_array_type(Array array, std::shared_ptr<TypeBase> &arr_type) {
76  arr_type = array.data_->type_of_values_;
77 }
78 
79 
80 
81 const string & OutputBase::get_record_description(const Record *rec) {
82  return rec->data_->description_;
83 }
84 
85 
86 
87 const string & OutputBase::get_abstract_description(const Abstract *a_rec) {
88  return a_rec->child_data_->description_;
89 }
90 
91 
92 
93 void OutputBase::get_parent_vec(Record rec, std::vector< std::shared_ptr<Abstract> > &parent_vec) {
94  parent_vec = rec.data_->parent_vec_;
95 }
96 
97 
98 
99 void OutputBase::get_default(Record::KeyIter it, string &type, string &value) {
100  value = it->default_.value_;
101  if ( it->default_.is_obligatory() ) {
102  type = "obligatory";
103  } else if ( it->default_.is_optional() ) {
104  type = "optional";
105  } else if ( it->default_.has_value_at_read_time() ) {
106  type = "value at read time";
107  } else {
108  type = "value at declaration";
109  }
110 
111 }
112 
113 
115  return sel->data_->description_;
116 }
117 
118 
119 void OutputBase::get_adhoc_parent_name(const AdHocAbstract *a_rec, string &parent_name) {
120  parent_name = a_rec->ancestor_.type_name();
121 }
122 
123 
125  return a_rec->ancestor_.child_data_->list_of_childs.begin();
126 }
127 
128 
129 
130 
131 void OutputBase::print_base(ostream& stream, const TypeBase *type) {
132 
133  if (typeid(*type) == typeid(Type::Record) || typeid(*type) == typeid(Type::Tuple)) {
134  print_impl(stream, static_cast<const Type::Record *>(type) );
135  } else
136  if (typeid(*type) == typeid(Type::Array)) {
137  print_impl(stream, static_cast<const Type::Array *>(type) );
138  } else
139  if (typeid(*type) == typeid(Type::Abstract)) {
140  print_impl(stream, static_cast<const Type::Abstract *>(type) );
141  } else
142  if (typeid(*type) == typeid(Type::AdHocAbstract)) {
143  print_impl(stream, static_cast<const Type::AdHocAbstract *>(type) );
144  } else
145  if (typeid(*type) == typeid(Type::Selection)) {
146  print_impl(stream, static_cast<const Type::Selection *>(type) );
147  } else
148  if (typeid(*type) == typeid(Type::Integer)) {
149  print_impl(stream, static_cast<const Type::Integer *>(type) );
150  } else
151  if (typeid(*type) == typeid(Type::Double)) {
152  print_impl(stream, static_cast<const Type::Double *>(type) );
153  } else
154  if (typeid(*type) == typeid(Type::Bool)) {
155  print_impl(stream, static_cast<const Type::Bool *>(type) );
156  } else
157  if (typeid(*type) == typeid(Type::Parameter)) {
158  print_impl(stream, static_cast<const Type::Parameter *>(type) );
159  } else {
160  const Type::FileName * file_name_type = dynamic_cast<const Type::FileName *>(type);
161  if (file_name_type != NULL ) {
162  print_impl(stream, file_name_type );
163  return;
164  }
165 
166  const Type::String * string_type = dynamic_cast<const Type::String *>(type);
167  if (string_type != NULL ) {
168  print_impl(stream, string_type );
169  return;
170  }
171 
172  // default -> error
173  THROW( Type::ExcUnknownDescendant() << Type::EI_TypeName(typeid(type).name()) );
174  }
175 }
176 
177 
178 void OutputBase::write_default_value(std::ostream& stream, Default dft) {
179  if (dft.is_obligatory() || dft.is_optional()) {
180  stream << "<" << dft.value() << ">";
181  } else {
182  stream << "\"" << dft.value() << "\"";
183  }
184 }
185 
186 void OutputBase::write_description(std::ostream& stream, const string& str,
187  unsigned int padding, unsigned int hash_count) {
188  string s = str;
189  boost::replace_all(s, "\\$", "$");
190 
191  boost::tokenizer<boost::char_separator<char> > line_tokenizer(s, boost::char_separator<char>("\n"));
192  boost::tokenizer<boost::char_separator<char> >::iterator it;
193 
194  // For every \n add padding at beginning of the next line.
195  for(it = line_tokenizer.begin(); it != line_tokenizer.end(); ++it) {
196  stream << endl;
197  stream << setw(padding) << "";
198  stream << std::setfill('#') << setw(hash_count) << "" << std::setfill(' ') << " " << *it;
199  }
200 }
201 
202 
204  processed_types_hash_.clear();
205  full_hash_ = 0;
206 }
207 
208 
209 bool OutputBase::was_written(std::size_t hash)
210 {
211  bool in_set = ( processed_types_hash_.find(hash) != processed_types_hash_.end() );
212  if (! in_set) processed_types_hash_.insert(hash);
213  return in_set;
214 }
215 
217  TypeBase::TypeHash &generic_type_hash, TypeBase::json_string &parameter_map_to_json) {
218  attr_map = *( type->attributes_.get() );
219  generic_type_hash = type->generic_type_hash_;
220  if (type->parameter_map_.size()) {
221  parameter_map_to_json = type->print_parameter_map_to_json( type->parameter_map_ );
222  }
223 }
224 
225 
226 
227 
228 /*******************************************************************
229  * implementation of OutputText
230  */
231 
232 ostream& OutputText::print(ostream& stream) {
233  doc_type_ = full_record;
234  clear_processed_types();
235 
236  print_base(stream, type_);
237  return stream;
238 }
239 
240 void OutputText::print_impl(ostream& stream, const Record *type) {
241  ASSERT(type->is_finished())(type->type_name())(type->class_name()).warning("Printing documentation of unfinished type.");
242  switch (doc_type_) {
243  case key_record:
244  stream << "" << type->class_name() << " '" << type->type_name() << "' (" << type->size() << " keys).";
245  break;
246  case full_record:
247  TypeBase::TypeHash hash=type->content_hash();
248  if (! was_written(hash)) {
249  // header
250  stream << endl;
251  stream << "" << type->class_name() << " '" << type->type_name() << "'";
252  // parent record
253  /*std::shared_ptr<Abstract> parent_ptr;
254  get_parent_ptr(*type, parent_ptr);
255  if (parent_ptr) {
256  stream << ", implementation of " << parent_ptr->type_name();
257  }*/
258 
259  // reducible to key
260  Record::KeyIter key_it = type->auto_conversion_key_iter();
261  if (key_it != type->end()) {
262  stream << ", reducible to key '" << key_it->key_ << "'";
263  }
264  stream << "" << " (" << type->size() << " keys).";
265  write_description(stream, OutputBase::get_record_description(type), 0);
266  stream << endl;
267  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << endl;
268  // keys
269  doc_type_ = key_record;
270  for (Record::KeyIter it = type->begin(); it != type->end(); ++it) {
271  size_setw_ = it->key_.size() + 3;
272  stream << setw(padding_size) << "" << it->key_ << " = ";
273  write_default_value(stream, it->default_);
274  stream << endl;
275  stream << setw(padding_size + size_setw_) << "" <<"#### is ";
276  print_base(stream, it->type_.get());
277  write_description(stream, it->description_, padding_size+size_setw_);
278  stream << endl;
279  }
280  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << " " << type->type_name() << endl;
281  // Full documentation of embedded record types.
282  doc_type_ = full_record;
283  }
284  break;
285  }
286 }
287 void OutputText::print_impl(ostream& stream, const Array *type) {
288  std::shared_ptr<TypeBase> array_type;
289  get_array_type(*type, array_type);
290  switch (doc_type_) {
291  case key_record:
292  unsigned int lower_size, upper_size;
293  get_array_sizes(*type, lower_size, upper_size);
294  stream << "Array, size limits: [" << lower_size << ", " << upper_size << "] of type: " << endl;
295  stream << setw(padding_size + size_setw_) << "" << "#### ";
296  print_base(stream, array_type.get());
297  break;
298  case full_record:
299  print_base(stream, array_type.get());
300  break;
301  }
302 }
303 
304 
305 void OutputText::print_impl(ostream& stream, const Abstract *type) {
306  // Print documentation of abstract record
307  switch (doc_type_) {
308  case key_record:
309  stream << "Abstract '" << type->type_name() << "' with "<< type->child_size() << " descendants.";
310  break;
311  case full_record:
312  TypeBase::TypeHash hash=type->content_hash();
313  if (! was_written(hash) ) {
314  // header
315  stream << endl;
316  stream << "" << "Abstract '" << type->type_name() << "' with " << type->child_size() << " descendants.";
317  write_description(stream, OutputBase::get_abstract_description( type ), 0);
318  stream << endl;
319  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << endl;
320  // descendants
321  doc_type_ = key_record;
322  for (Abstract::ChildDataIter it = type->begin_child_data(); it != type->end_child_data(); ++it) {
323  size_setw_ = 0;
324  stream << setw(padding_size) << "";
325  stream << "" << "Record '" << (*it).type_name() << "'";
326  write_description(stream, OutputBase::get_record_description( &(*it) ), padding_size+size_setw_);
327  stream << endl;
328  }
329  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << " " << type->type_name() << endl;
330  // Full documentation of embedded record types.
331  doc_type_ = full_record;
332  }
333  break;
334  }
335 }
336 
337 
338 void OutputText::print_impl(ostream& stream, const AdHocAbstract *type) {
339  // Print documentation of adhoc abstract record
340  if (doc_type_ == key_record) {
341  stream << "AdHocAbstract";
342  /*string parent_name;
343  get_adhoc_parent_name(type, parent_name);
344  stream << "AdHocAbstract" << endl;
345  stream << setw(padding_size + size_setw_) << "";
346  stream << "#### Derived from Abstract '" << parent_name << "', ";
347  stream << "added Records: ";
348  {
349  Abstract::ChildDataIter parent_it = get_adhoc_parent_data(type);
350  bool add_comma = false;
351  for (Abstract::ChildDataIter it = type->begin_child_data(); it != type->end_child_data(); ++it) {
352  if ((*it).type_name() == (*parent_it).type_name()) {
353  ++parent_it;
354  } else {
355  if (add_comma) stream << ", ";
356  else add_comma = true;
357  stream << "'" << (*it).type_name() << "'";
358  }
359  }
360  }*/
361  }
362 }
363 void OutputText::print_impl(ostream& stream, const Selection *type) {
364  ASSERT(type->is_finished())(type->type_name()).warning("Printing documentation of unfinished Input::Type::Selection.");
365  switch (doc_type_) {
366  case key_record:
367  stream << "Selection '" << type->type_name() << "' of " << type->size() << " values.";
368  break;
369  case full_record:
370  TypeBase::TypeHash hash=type->content_hash();
371  if (! was_written(hash) ) {
372  stream << endl << "Selection '" << type->type_name() << "' of " << type->size() << " values.";
373  write_description(stream, OutputBase::get_selection_description( type ), 0);
374  stream << endl;
375  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << endl;
376  // keys
377  for (Selection::keys_const_iterator it = type->begin(); it != type->end(); ++it) {
378  stream << setw(padding_size) << "" << it->key_ << " = " << it->value;
379  if (it->description_ != "") {
380  stream << endl;
381  stream << setw(padding_size + it->key_.size() + 3) << "" << "# " << it->description_ << "";
382  }
383  stream << endl;
384  }
385  stream << "" << std::setfill('-') << setw(10) << "" << std::setfill(' ') << " " << type->type_name() << endl;
386  }
387  break;
388  }
389 }
390 void OutputText::print_impl(ostream& stream, const Integer *type) {
391  if (doc_type_ == key_record) {
392  int lower_bound, upper_bound;
393  get_integer_bounds(*type, lower_bound, upper_bound);
394  stream << "Integer in [" << lower_bound << ", " << upper_bound << "]";
395  }
396 }
397 void OutputText::print_impl(ostream& stream, const Double *type) {
398  if (doc_type_ == key_record) {
399  double lower_bound, upper_bound;
400  get_double_bounds(*type, lower_bound, upper_bound);
401  stream << "Double in [" << lower_bound << ", " << upper_bound << "]";
402  }
403 }
404 void OutputText::print_impl(ostream& stream, const Bool *type) {
405  if (doc_type_ == key_record) {
406  stream << "Bool";
407  }
408 }
409 void OutputText::print_impl(ostream& stream, const String *type) {
410  if (doc_type_ == key_record) {
411  stream << "String (generic)";
412  }
413 }
414 void OutputText::print_impl(ostream& stream, const FileName *type) {
415  if (doc_type_ == key_record) {
416  stream << "FileName of ";
417  switch (type->get_file_type()) {
418  case ::FilePath::input_file:
419  stream << "input file";
420  break;
421  case ::FilePath::output_file:
422  stream << "output file";
423  break;
424  default:
425  stream << "file with unknown type";
426  break;
427  }
428  }
429 }
430 
431 
432 
433 void OutputText::print_impl(ostream& stream, const Parameter *type) {
434  ASSERT_DBG(false).error("Parameter appears in the IST. Check where Instance is missing.");
435 }
436 
437 
438 
439 
440 /*******************************************************************
441  * implementation of OutputJSONMachine
442  */
443 
445 : OutputBase()
446 {
447  rev_num_data_ = rev_num_data;
448 
449  format_head="{ \"version\" :";
450  format_inner=",\n\"ist_nodes\" : [\n";
451  format_full_hash="{}],\n";
452  format_tail="}\n";
453 }
454 
455 
456 
458 : OutputJSONMachine(rev_num_data)
459 {
460  root_type_ = root_type;
461 }
462 
463 
464 std::string OutputJSONMachine::escape_description(std::string desc) {
465  static std::vector< std::pair<boost::regex, std::string> > rewrite_rules = {
466  // replace single slash with two slashes
467  {boost::regex("\\\\"), "\\\\\\\\"},
468  // replace quote with slash quote
469  {boost::regex("\\\""), "\\\\\""},
470  // replace special chars with escaped slash + special chars
471  {boost::regex("\\n"), "\\\\n"},
472  {boost::regex("\\t"), "\\\\t"},
473  {boost::regex("\\r"), "\\\\r"}
474  };
475 
476 
477  std::string tmp = std::string(desc);
478 
479  for (auto rewrite_rule : rewrite_rules) {
480  tmp = boost::regex_replace(tmp, rewrite_rule.first, rewrite_rule.second);
481  }
482 
483  return tmp;
484 }
485 
486 
487 ostream& OutputJSONMachine::print(ostream& stream) {
490 
491  stream << format_head;
492  print_program_info(stream);
493  stream << format_inner;
494 
495  print_base( stream, &root_type_);
498  print_base( stream, it->second.get() );
499  }
502  print_base( stream, it->second.get() );
503  }
506  print_base( stream, it->second.get() );
507  }
508 
509  stream << format_full_hash;
510  print_full_hash(stream);
511  stream << format_tail;
512  return stream;
513 }
514 
515 std::string print_attributes(TypeBase::attribute_map attribute_map) {
516  stringstream stream;
517 
518  if (attribute_map.size() == 0) return "\"attributes\" : {}";
519 
520  stream << "\"attributes\" : {" << endl; // print map of attributes
521  for (auto it=attribute_map.begin(); it!=attribute_map.end(); ++it) {
522  if (it != attribute_map.begin()) {
523  stream << "," << endl;
524  }
525  stream << "\"" << it->first << "\" : " << it->second;
526  }
527  stream << endl << "}";
528 
529  return stream.str();
530 }
531 
532 
533 void OutputJSONMachine::print_type_header(ostream &stream, const TypeBase *type) {
534  stream << "{" << endl;
535  stream << "\"id\" : " << type->hash_str() << "," << endl;
536  stream << "\"input_type\" : \"" + type->class_name() + "\"," << endl;
537  stream << "\"name\" : \"" << type->type_name() << "\"," << endl;
538 
539  // write data of parameters and attributes
540  TypeBase::attribute_map attr_map;
541  TypeBase::TypeHash generic_type_hash;
542  TypeBase::json_string parameter_map_to_json;
543  get_attr_and_param_data(type, attr_map, generic_type_hash, parameter_map_to_json);
544  // print hash of generic type and parameters into separate keys
545  if (generic_type_hash) { // print hash of generic type into separate keys
546  stream << "\"generic_type\" : " << TypeBase::hash_str(generic_type_hash) << "," << endl;
547  }
548  if (parameter_map_to_json.size()) { // parameters into separate keys
549  stream << "\"parameters\" : " << parameter_map_to_json << "," << endl;
550  }
551  stream << print_attributes(attr_map);
552 }
553 
554 
555 void OutputJSONMachine::print_impl(ostream& stream, const Record *type) {
556 
557  TypeBase::TypeHash hash=type->content_hash();
558  if (was_written(hash)) return;
559 
560  print_type_header(stream, type);
561  stream << "," << endl << "\"description\" : \"" <<
562  escape_description( OutputBase::get_record_description(type) ) << "\"," << endl;
563 
564  // parent records, implemented abstracts
566  get_parent_vec(*type, parent_vec);
567  if (parent_vec.size()) {
568  stream << "\"implements\" : [ ";
569  bool add_comma = false;
570  for (auto &parent : parent_vec) {
571  if (add_comma) stream << ", ";
572  else add_comma = true;
573  stream << parent->hash_str();
574  }
575  stream << " ]," << endl;
576  }
577 
578  // reducible to key
579  Record::KeyIter key_it = type->auto_conversion_key_iter();
580  if (key_it != type->end()) {
581  stream << "\"reducible_to_key\" : \"" << key_it->key_ << "\"," << endl;
582  }
583 
584  stream << "\"keys\" : [" << endl;
585 
587  for (Record::KeyIter it = type->begin(); it != type->end(); ++it) {
588  string dft_type, dft_value;
589  get_default(it, dft_type, dft_value);
590  if (dft_type != "value at declaration")
591  dft_value = "\"" + escape_description(dft_value) + "\"";
592 
593  if (it != type->begin()) {
594  stream << "," << endl;
595  }
596  stream << "{ \"key\" : \"" << it->key_ << "\"," << endl;
597  stream << "\"description\" : \"" <<
598  escape_description(it->description_) << "\"," << endl;
599  stream << "\"default\" : { "
600  <<"\"type\" : \"" << dft_type << "\"," << endl
601  <<"\"value\" : " << dft_value << " }," << endl;
602  stream << "\"type\" : " << it->type_->hash_str() << "," << endl;
603  stream << print_attributes(it->attributes);
604  stream << "}";
605  }
606 
607  stream << "]" << endl;
608  stream << "},";
609 
610  // Full documentation of embedded record types.
612  for (Record::KeyIter it = type->begin(); it != type->end(); ++it) {
613  print_base(stream, it->type_.get());
614  }
615 
616  boost::hash_combine(full_hash_, hash);
617 }
618 
619 
620 
621 void OutputJSONMachine::print_impl(ostream& stream, const Array *type) {
622  TypeBase::TypeHash hash=type->content_hash();
623  if (was_written(hash)) return;
624 
625  unsigned int lower_size, upper_size;
626  std::shared_ptr<TypeBase> array_type;
627 
628  get_array_sizes(*type, lower_size, upper_size);
629  get_array_type(*type, array_type);
630 
631  print_type_header(stream, type);
632  stream << "," << endl;
633  stream << "\"range\" : [" << lower_size << ", " << upper_size << "]," << endl;
634  stream << "\"subtype\" : " << array_type->hash_str() << endl;
635  stream << "}," << endl;
636 
637  print_base(stream, array_type.get());
638 
639  boost::hash_combine(full_hash_, hash);
640 }
641 
642 
643 
644 void OutputJSONMachine::print_impl(ostream& stream, const Abstract *type) {
645  TypeBase::TypeHash hash=type->content_hash();
646  if (was_written(hash)) return;
647 
648  print_type_header(stream, type);
649  stream << "," << endl;
650  stream << "\"description\" : \"" <<
652 
653  print_abstract_record_keys(stream, type);
654  stream << "},";
655 
656  for (Abstract::ChildDataIter it = type->begin_child_data(); it != type->end_child_data(); ++it) {
657  print_base(stream, &*it);
658  }
659 
660  boost::hash_combine(full_hash_, hash);
661 }
662 
663 
664 void OutputJSONMachine::print_impl(ostream& stream, const AdHocAbstract *type) {
665  TypeBase::TypeHash hash=type->content_hash();
666  if (was_written(hash)) return;
667 
668  string parent_name;
669  get_adhoc_parent_name(type, parent_name);
670  print_type_header(stream, type);
671  stream << "," << endl;
672  print_abstract_record_keys(stream, dynamic_cast<const Type::Abstract *>(type));
673  stream << "},";
674 
675  for (Abstract::ChildDataIter it = type->begin_child_data(); it != type->end_child_data(); ++it) {
676  print_base(stream, &*it);
677  }
678 
679  boost::hash_combine(full_hash_, hash);
680 }
681 
682 
683 
684 void OutputJSONMachine::print_abstract_record_keys(ostream& stream, const Abstract *type) {
685 
686  // Print documentation of abstract record
687  const Record * desc = type->get_default_descendant();
688 
689  // default descendant
690  if (desc) {
691  stream << "\"default_descendant\" : " << desc->hash_str() << "," << endl;
692  }
693  stream << "\"implementations\" : [" << endl;
694  for (Abstract::ChildDataIter it = type->begin_child_data(); it != type->end_child_data(); ++it) {
695  if (it != type->begin_child_data())
696  stream << "," << endl;
697  stream << "" << it->hash_str() << "";
698  }
699  stream << "]";
700 
701 }
702 
703 
704 
705 
706 
707 void OutputJSONMachine::print_impl(ostream& stream, const Selection *type) {
708  TypeBase::TypeHash hash=type->content_hash();
709  if (was_written(hash)) return;
710 
711  print_type_header(stream, type);
712  stream << "," << endl;
713  stream << "\"description\" : \"" <<
715 
716  stream << "\"values\" : [" << endl;
717  for (Selection::keys_const_iterator it = type->begin(); it != type->end(); ++it) {
718  if (it != type->begin()) {
719  stream << "," << endl;
720  }
721  stream << "{ \"name\" : \"" << it->key_ << "\"," << endl
722  << "\"description\" : \"" << escape_description(it->description_) << "\" }";
723  }
724 
725  stream << "]" << endl;
726  stream << "},";
727 
728  boost::hash_combine(full_hash_, hash);
729 }
730 
731 
732 void OutputJSONMachine::print_impl(ostream& stream, const Integer *type) {
733  TypeBase::TypeHash hash=type->content_hash();
734  if (was_written(hash)) return;
735 
736  int lower, upper;
737  get_integer_bounds(*type, lower, upper);
738 
739  print_type_header(stream, type);
740  stream << "," << endl;
741  stream << "\"range\" : [" << lower << ", " << upper << "]" << endl;
742  stream << "},";
743 
744  boost::hash_combine(full_hash_, hash);
745 }
746 
747 
748 void OutputJSONMachine::print_impl(ostream& stream, const Double *type) {
749  TypeBase::TypeHash hash=type->content_hash();
750  if (was_written(hash)) return;
751 
752  double lower, upper;
753  get_double_bounds(*type, lower, upper);
754 
755  print_type_header(stream, type);
756  stream << "," << endl;
757  stream << "\"range\" : [" << lower << ", " << upper << "]" << endl;
758  stream << "},";
759 
760  boost::hash_combine(full_hash_, hash);
761 }
762 
763 
764 void OutputJSONMachine::print_impl(ostream& stream, const Bool *type) {
765  TypeBase::TypeHash hash=type->content_hash();
766  if (was_written(hash)) return;
767 
768  print_type_header(stream, type);
769  stream << "},";
770 
771  boost::hash_combine(full_hash_, hash);
772 }
773 
774 
775 void OutputJSONMachine::print_impl(ostream& stream, const String *type) {
776  TypeBase::TypeHash hash=type->content_hash();
777  if (was_written(hash)) return;
778 
779  print_type_header(stream, type);
780  stream << "},";
781 
782  boost::hash_combine(full_hash_, hash);
783 }
784 
785 
786 void OutputJSONMachine::print_impl(ostream& stream, const FileName *type) {
787  TypeBase::TypeHash hash=type->content_hash();
788  if (was_written(hash)) return;
789 
790  print_type_header(stream, type);
791  stream << "," << endl;
792  stream << "\"file_mode\" : \"";
793  switch (type->get_file_type()) {
794  case ::FilePath::input_file:
795  stream << "input\"";
796  break;
797  case ::FilePath::output_file:
798  stream << "output\"";
799  break;
800  }
801 
802  stream << endl << "},";
803 
804  boost::hash_combine(full_hash_, hash);
805 }
806 
807 
808 
809 void OutputJSONMachine::print_impl(ostream& stream, const Parameter *type) {
810  TypeBase::TypeHash hash=type->content_hash();
811  if (was_written(hash)) return;
812 
813  print_type_header(stream, type);
814  stream << endl << "},";
815 
816  boost::hash_combine(full_hash_, hash);
817 }
818 
819 
820 
822  string build_date = string(__DATE__) + ", " + string(__TIME__);
823 
824  stream << "{" << endl;
825  stream << "\"flow123d_commit\" : \"" << rev_num_data_.revision << "\"," << endl;
826  stream << "\"flow123d_version\" : \"" << rev_num_data_.version << "\"," << endl;
827  stream << "\"date\" : \"" << build_date << "\"" << endl;
828  stream << "}";
829 }
830 
831 
832 
833 void OutputJSONMachine::print_full_hash(ostream& stream) {
834  stream << "\"IST_hash\" : " << TypeBase::hash_str( full_hash_ ) << endl;
835 }
836 
837 
838 
839 
840 
841 
842 std::ostream& operator<<(std::ostream& stream, OutputText type_output) {
843  return type_output.print(stream) << endl;
844 }
845 
846 
847 std::ostream& operator<<(std::ostream& stream, OutputJSONMachine type_output) {
848  return type_output.print(stream) << endl;
849 }
850 
851 
852 } // closing namespace Type
853 } // closing namespace Input
std::string escape_description(std::string desc)
Replace slashes, quotes and special chars with escaped format of these chars.
Definition: type_output.cc:464
std::int64_t lower_bound_
Minimal value of Integer.
Definition: type_base.hh:505
Base of classes for declaring structure of the input data.
Definition: type_base.hh:79
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:319
unsigned int size() const
Returns number of values in the Selection.
bool was_written(std::size_t hash)
Returns true if the type was printed out.
Definition: type_output.cc:209
std::string print_attributes(TypeBase::attribute_map attribute_map)
Definition: type_output.cc:515
TypeRepositoryMap::const_iterator TypeRepositoryMapIter
Public typedef of constant iterator into map of stored type.
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:382
std::vector< struct Key >::const_iterator KeyIter
Public typedef of constant iterator into array of keys.
Definition: type_record.hh:206
std::string hash_str() const
Format the hash of this type.
Definition: type_base.hh:202
std::string format_tail
Tail of the format, printed after all recursive prints are finished.
Definition: type_output.hh:311
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:582
virtual string class_name() const
Returns an identification of the class. Useful for output of the documentation.
Definition: type_base.hh:118
std::vector< Record >::const_iterator ChildDataIter
Public typedef of constant iterator into array of keys.
void write_default_value(std::ostream &stream, Default dft)
Write value stored in dft.
Definition: type_output.cc:178
void get_default(Record::KeyIter it, string &type, string &value)
Gets values of default for given record key.
Definition: type_output.cc:99
void get_integer_bounds(Integer integer, int &lower, int &upper)
Gets range of integer.
Definition: type_output.cc:54
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:50
std::string format_head
Header of the format, printed before call of version print.
Definition: type_output.hh:293
Class for declaration of the input of type Bool.
Definition: type_base.hh:434
std::string format_inner
Inner part of the format, printed before first call of recursive print.
Definition: type_output.hh:299
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_record.cc:299
std::string format_full_hash
Tail of the format, printed after all recursive prints are finished and before full hash prints...
Definition: type_output.hh:305
void clear_processed_types()
Clear all data of processed types.
Definition: type_output.cc:203
Base abstract class for output description of the Input::Type tree.
Definition: type_output.hh:58
std::shared_ptr< SelectionData > data_
Handle to actual Selection data.
virtual string type_name() const override
Implements Type::TypeBase::type_name.
Class for representing parametric types in IST.
Definition: type_generic.hh:52
TypeHash content_hash() const override
Implements TypeBase::content_hash.
DocumentationType doc_type_
Type of documentation output.
Definition: type_output.hh:173
Class for create JSON machine readable documentation.
Definition: type_output.hh:243
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:351
OutputBase()
Constructor.
Definition: type_output.cc:47
virtual string type_name() const
Returns an identification of the type. Useful for error messages.
Definition: type_base.hh:116
static std::string hash_str(TypeHash hash)
Format given hash for output.
Definition: type_base.cc:97
Class for declaration of the input data that are file names.
Definition: type_base.hh:597
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
Class for declaration of polymorphic Record.
Record root_type_
Root type for output.
Definition: type_output.hh:320
void print_impl(ostream &stream, const Record *type)
Implements printout of Record type.
Definition: type_output.cc:240
std::shared_ptr< attribute_map > attributes_
map of type attributes (e. g. input_type, name etc.)
Definition: type_base.hh:280
TypeBase::TypeHash full_hash_
Content hash of full IST, value is used for key IST_hash.
Definition: type_output.hh:180
void print_full_hash(ostream &stream)
Print full_hash_ key.
Definition: type_output.cc:833
Class for declaration of the integral input data.
Definition: type_base.hh:465
KeyIter begin() const
Container-like access to the keys of the Record.
Definition: type_record.hh:559
void get_array_sizes(Array array, unsigned int &lower, unsigned int &upper)
Gets range of array.
Definition: type_output.cc:68
bool is_optional() const
Returns true if the key is optional.
Definition: type_record.hh:130
const Abstract & ancestor_
Reference to ancestor Abstract.
Class for declaration of inputs sequences.
Definition: type_base.hh:321
double upper_bound_
Maximal value of Integer.
Definition: type_base.hh:555
static TypeRepository & get_instance()
Return singleton instance of class.
ParameterMap parameter_map_
map of parameters if type is part of generic subtree
Definition: type_base.hh:289
const string & get_record_description(const Record *rec)
Gets description of the given record type.
Definition: type_output.cc:81
std::shared_ptr< ArrayData > data_
Handle to the actual array data.
Definition: type_base.hh:411
unsigned int child_size() const
Returns number of descendants in the child_data_.
void print_type_header(ostream &stream, const TypeBase *type)
Print header of a JSON object describing single TypeBase instance.
Definition: type_output.cc:533
Stores version of program and other base data of application.
Definition: type_output.hh:37
RevNumData rev_num_data_
Contains version of program and other base data.
Definition: type_output.hh:313
void print_abstract_record_keys(ostream &stream, const Abstract *type)
Print all keys of Abstract type or AdHocAbstract type.
Definition: type_output.cc:684
void get_double_bounds(Double dbl, double &lower, double &upper)
Gets range of double.
Definition: type_output.cc:61
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:518
void print_program_info(ostream &stream)
Print actual version of program.
Definition: type_output.cc:821
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:179
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:423
static void lazy_finish()
Finishes all types registered in type repositories.
Definition: type_base.cc:85
ostream & print(ostream &stream) override
Performs output of the documentation into given stream.
Definition: type_output.cc:487
virtual TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_record.cc:122
string type_name() const override
Implements Type::TypeBase::type_name.
Printout only basic data.
Definition: type_output.hh:76
std::int64_t upper_bound_
Maximal value of Integer.
Definition: type_base.hh:506
ostream & print(ostream &stream) override
Performs output of the documentation into given stream.
Definition: type_output.cc:232
TypeHash content_hash() const override
Implements TypeBase::content_hash.
const string & get_abstract_description(const Abstract *a_rec)
Gets description of the given abstract type.
Definition: type_output.cc:87
void print_base(ostream &stream, const TypeBase *type)
Perform resolution according to actual type (using typeid) and call particular print_impl method...
Definition: type_output.cc:131
keys_const_iterator end() const
Container-like access to the keys of the Selection.
const Record * get_default_descendant() const
Returns default descendant.
Class for declaration of polymorphic Record.
Abstract::ChildDataIter get_adhoc_parent_data(const AdHocAbstract *a_rec)
Gets iterator to begin of ancestor_.child_data_ of the given AdHocAbstract type.
Definition: type_output.cc:124
TypeRepositoryMapIter end() const
Container-like access to the data stored in TypeRepository. Returns iterator to the last data...
ChildDataIter begin_child_data() const
Container-like access to the descendants of the Abstract.
Printout full documentation.
Definition: type_output.hh:77
void get_adhoc_parent_name(const AdHocAbstract *a_rec, string &parent_name)
Gets ancestor_.type_name of the given AdHocAbstract type.
Definition: type_output.cc:119
std::string revision
Actual revision of application.
Definition: type_output.hh:39
Tuple type proxy class.
Definition: type_tuple.hh:41
TypeHash generic_type_hash_
hash string of generic type if type is derived, or empty string
Definition: type_base.hh:286
json_string print_parameter_map_to_json(ParameterMap parameter_map) const
Create JSON output from parameter_map formatted as value of attribute.
Definition: type_base.cc:123
The Singleton class TypeRepository serves for handling the lazy-evaluated input types, derived from the base class Type::TypeBase.
void get_parent_vec(Record rec, std::vector< std::shared_ptr< Abstract > > &parent_vec)
Gets pointer of parent Abstract for given Record.
Definition: type_output.cc:93
::FilePath::FileType get_file_type() const
Returns type of the file input/output.
Definition: type_base.hh:637
const string & get_selection_description(const Selection *sel)
Gets description of the given selection type.
Definition: type_output.cc:114
void write_description(std::ostream &stream, const string &str, unsigned int padding, unsigned int hash_count=1)
Write out a string with given padding of every new line.
Definition: type_output.cc:186
void get_attr_and_param_data(const TypeBase *type, TypeBase::attribute_map &attr_map, TypeBase::TypeHash &generic_type_hash, TypeBase::json_string &parameter_map_to_json)
Gets data of attributes and parameters of the given type.
Definition: type_output.cc:216
TypeRepositoryMapIter begin() const
Container-like access to the data stored in TypeRepository. Returns iterator to the first data...
#define ASSERT_DBG(expr)
Definition: asserts.hh:350
KeyIter end() const
Container-like access to the keys of the Record.
Definition: type_record.hh:567
ChildDataIter end_child_data() const
Container-like access to the descendants of the Abstract.
double lower_bound_
Minimal value of Integer.
Definition: type_base.hh:554
std::string json_string
String stored in JSON format.
Definition: type_base.hh:85
virtual ~OutputBase()
Destructor.
Definition: type_output.cc:43
std::ostream & operator<<(std::ostream &stream, const TypeBase &type)
For convenience we provide also redirection operator for output documentation of Input:Type classes...
Definition: type_base.cc:169
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:298
Class for create text documentation.
Definition: type_output.hh:199
Record type proxy class.
Definition: type_record.hh:171
std::string version
Actual version of application.
Definition: type_output.hh:38
const string & value() const
Returns stored value. Possibly empty string.
Definition: type_record.hh:134
std::shared_ptr< ChildData > child_data_
Actual data of the Abstract.
std::vector< struct Key >::const_iterator keys_const_iterator
Public typedef of constant iterator into array of keys.
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_generic.cc:48
void get_array_type(Array array, std::shared_ptr< TypeBase > &arr_type)
Gets pointer of inner type for given Array.
Definition: type_output.cc:75
keys_const_iterator begin() const
Container-like access to the keys of the Selection.
std::shared_ptr< RecordData > data_
Data handle.
Definition: type_record.hh:511
bool is_finished() const override
Implements TypeBase::is_finished.
Definition: type_record.cc:222
bool is_obligatory() const
Returns true if the key is obligatory and thus must be specified on input. No default value is given...
Definition: type_record.hh:126
Class for declaration of the input data that are in string format.
Definition: type_base.hh:568
std::size_t TypeHash
Type returned by content_hash methods.
Definition: type_base.hh:82
bool is_finished() const override
Implements TypeBase::is_finished.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:45
virtual string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_record.hh:332
Template for classes storing finite set of named values.
OutputJSONMachine(RevNumData rev_num_data)
Simple constructor.
Definition: type_output.cc:444
KeyIter auto_conversion_key_iter() const
Returns iterator to auto-conversion key.
Definition: type_record.cc:311
void print_impl(ostream &stream, const Record *type)
Implements printout of Record type.
Definition: type_output.cc:555