Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "JsonInputFileFormatter.h" 11 : #include "MooseUtils.h" 12 : 13 : #include <vector> 14 : 15 14 : JsonInputFileFormatter::JsonInputFileFormatter() : _spaces(2), _level(0) {} 16 : 17 : std::string 18 14 : JsonInputFileFormatter::toString(const nlohmann::json & root) 19 : { 20 14 : _stream.clear(); 21 28 : _stream.str(""); 22 550 : for (auto && el : root["blocks"].items()) 23 550 : addBlock(el.key(), el.value(), true); 24 14 : return _stream.str(); 25 : } 26 : 27 : void 28 1061913 : JsonInputFileFormatter::addLine(const std::string & line, 29 : size_t max_line_len, 30 : const std::string & comment) 31 : { 32 1061913 : if (line.empty() && comment.empty()) 33 : { 34 19634 : _stream << "\n"; 35 58902 : return; 36 : } 37 : 38 2084558 : std::string indent(_level * _spaces, ' '); 39 1042279 : auto doc = MooseUtils::trim(comment); 40 1042279 : if (doc.empty()) // Not comment so just print out the line normally 41 : { 42 39268 : _stream << indent << line << "\n"; 43 39268 : return; 44 : } 45 : 46 : // We have a comment so we need to break it up over multiple lines if necessary 47 : // and make sure that they all start at the same spot. 48 1003011 : _stream << indent << line; 49 1003011 : std::vector<std::string> elements; 50 : 51 : // if the line is empty we can just start the comment right away 52 1003011 : int extra = 1; 53 1003011 : if (line.empty()) 54 674663 : extra = 0; 55 : 56 : // be careful of really long lines. 57 1003011 : int len = 100 - max_line_len - indent.size(); 58 1003011 : if (len < 0) 59 3136 : len = 20; 60 : 61 2006022 : MooseUtils::tokenize(doc, elements, len, " \t"); 62 1003011 : std::string first(max_line_len - line.size() + extra, ' '); 63 1003011 : _stream << first << "# " << elements[0] << "\n"; 64 1003011 : std::string cindent(max_line_len + indent.size() + extra, ' '); 65 1644702 : for (size_t i = 1; i < elements.size(); ++i) 66 641691 : _stream << cindent << "# " << elements[i] << "\n"; 67 : 68 1003011 : _stream << std::flush; 69 1081547 : } 70 : 71 : void 72 19147 : JsonInputFileFormatter::addBlock(const std::string & name, 73 : const nlohmann::json & block, 74 : bool toplevel) 75 : { 76 57441 : addLine(""); 77 19147 : if (toplevel) 78 1072 : addLine("[" + name + "]"); 79 : else 80 37222 : addLine("[./" + name + "]"); 81 : 82 19147 : _level++; 83 20327 : std::string desc = block.contains("description") ? nlohmann::to_string(block["description"]) : ""; 84 19147 : if (!desc.empty()) 85 35934 : addLine("", 0, desc); 86 : 87 19147 : if (block.contains("parameters")) 88 17967 : addParameters(block["parameters"]); 89 : 90 19147 : if (block.contains("actions")) 91 : { 92 : // there could be duplicate parameters across actions, last one wins 93 732 : nlohmann::json all_params; 94 732 : auto & actions = block["actions"]; 95 1555 : for (auto && el : actions.items()) 96 : { 97 823 : auto & params = el.value()["parameters"]; 98 6341 : for (auto && param_el : params.items()) 99 6341 : all_params[param_el.key()] = param_el.value(); 100 732 : } 101 732 : addParameters(all_params); 102 732 : } 103 : 104 19147 : if (block.contains("star")) 105 1428 : addBlock("*", block["star"]); 106 : 107 38294 : addTypes("subblock_types", block); 108 19147 : addTypes("types", block); 109 : 110 19147 : if (block.contains("subblocks")) 111 : { 112 77 : auto & subblocks = block["subblocks"]; 113 77 : if (!subblocks.is_null()) 114 245 : for (auto && el : subblocks.items()) 115 245 : addBlock(el.key(), el.value()); 116 : } 117 : 118 19147 : _level--; 119 19147 : if (toplevel) 120 2144 : addLine("[]"); 121 : else 122 74444 : addLine("[../]"); 123 19147 : } 124 : 125 : void 126 38294 : JsonInputFileFormatter::addTypes(const std::string & key, const nlohmann::json & block) 127 : { 128 38294 : if (!block.contains(key)) 129 37562 : return; 130 732 : auto & types = block[key]; 131 732 : if (types.is_null()) 132 245 : return; 133 : 134 1948 : addLine(""); 135 1461 : addLine("[./<types>]"); 136 487 : _level++; 137 18454 : for (auto && el : types.items()) 138 18454 : addBlock("<" + el.key() + ">", el.value()); 139 487 : _level--; 140 1948 : addLine("[../]"); 141 : } 142 : 143 : void 144 18699 : JsonInputFileFormatter::addParameters(const nlohmann::json & params) 145 : { 146 18699 : size_t max_name = 0; 147 347047 : for (auto & el : params.items()) 148 328348 : if (el.key().size() > max_name) 149 62128 : max_name = el.key().size(); 150 : 151 18699 : size_t max_len = 0; 152 18699 : std::map<std::string, std::string> lines; 153 347047 : for (auto && el : params.items()) 154 : { 155 328348 : auto & name = el.key(); 156 328348 : auto & param = el.value(); 157 : auto def = 158 764411 : param.contains("default") ? MooseUtils::trim(nlohmann::to_string(param["default"])) : ""; 159 328348 : if (!def.empty()) 160 220633 : def = def.substr(1, def.size() - 2); 161 328348 : if (def.find(' ') != std::string::npos) 162 6752 : def = "'" + def + "'"; 163 328348 : std::string indent(max_name - name.size(), ' '); 164 328348 : std::string required; 165 328348 : if (param["required"]) 166 31316 : required = "(required)"; 167 328348 : if (def.size() == 0 && required.size() == 0) 168 110527 : def = "(no_default)"; 169 328348 : std::string l = name + indent + " = " + def + required; 170 328348 : if (l.size() > max_len) 171 45810 : max_len = l.size(); 172 328348 : lines[name] = l; 173 347047 : } 174 347047 : for (auto & el : params.items()) 175 : { 176 328348 : auto & name = el.key(); 177 328348 : auto & param = el.value(); 178 328348 : auto & l = lines[name]; 179 328348 : auto desc = nlohmann::to_string(param["description"]); 180 328348 : addLine(l, max_len, desc); 181 : 182 328348 : const auto doc_unit = nlohmann::to_string(param["doc_unit"]); 183 328348 : if (!doc_unit.empty()) 184 656696 : addLine("", max_len + 1, 185 656696 : "Unit: " + doc_unit); // a +1 to account for an empty line 186 : 187 328348 : const auto group = nlohmann::to_string(param["group_name"]); 188 328348 : if (!group.empty()) 189 656696 : addLine("", max_len + 1, 190 656696 : "Group: " + group); // a +1 to account for an empty line 191 347047 : } 192 18699 : }