this repo has no description
at develop 4.9 kB view raw
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 3/* 4 * Main authors: 5 * Jason Nguyen <jason.nguyen@monash.edu> 6 */ 7 8/* This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 11 12#include <minizinc/json_parser.hh> 13#include <minizinc/param_config.hh> 14#include <minizinc/prettyprinter.hh> 15 16#include <sstream> 17 18namespace MiniZinc { 19 20void ParamConfig::load(const std::string& filename) { 21 if (JSONParser::fileIsJSON(filename)) { 22 try { 23 Env confenv; 24 JSONParser jp(confenv.envi()); 25 Model m; 26 GCLock lock; 27 jp.parse(&m, filename, false); 28 for (auto& i : m) { 29 if (auto* ai = i->dynamicCast<AssignI>()) { 30 addValue(ai->id(), ai->e()); 31 } else if (auto* ii = i->dynamicCast<IncludeI>()) { 32 auto flag = ParamConfig::flagName(ii->f()); 33 if (_blacklist.count(flag) > 0) { 34 throw ParamException("Parameter '" + flag + "' is not allowed in configuration file"); 35 } 36 _values.push_back(flag); 37 _values.push_back(ParamConfig::modelToString(*(ii->m()))); 38 } 39 } 40 } catch (ParamException& e) { 41 throw; 42 } catch (Exception& e) { 43 throw ParamException(e.what()); 44 } 45 } else { 46 throw ParamException("Invalid configuration file"); 47 } 48} 49 50void ParamConfig::addValue(const ASTString& flag_input, Expression* e) { 51 auto flag = ParamConfig::flagName(flag_input); 52 if (_blacklist.count(flag) > 0) { 53 throw ParamException("Parameter '" + flag + "' is not allowed in configuration file"); 54 } 55 std::stringstream val_ss; 56 switch (e->eid()) { 57 case Expression::E_ARRAYLIT: { 58 auto* al = e->cast<ArrayLit>(); 59 for (auto* exp : al->getVec()) { 60 addValue(flag, exp); 61 } 62 break; 63 } 64 case Expression::E_BOOLLIT: { 65 if (e->cast<BoolLit>()->v()) { 66 _values.push_back(flag); 67 } else { 68 // If this flag has a negated version, use it 69 auto it = _boolSwitches.find(flag); 70 if (it != _boolSwitches.end()) { 71 _values.push_back(it->second); 72 } 73 } 74 break; 75 } 76 case Expression::E_STRINGLIT: 77 _values.push_back(flag); 78 val_ss << e->cast<StringLit>()->v(); 79 _values.push_back(val_ss.str()); 80 break; 81 case Expression::E_INTLIT: 82 _values.push_back(flag); 83 val_ss << e->cast<IntLit>()->v(); 84 _values.push_back(val_ss.str()); 85 break; 86 case Expression::E_FLOATLIT: 87 _values.push_back(flag); 88 val_ss << e->cast<FloatLit>()->v(); 89 val_ss << e; 90 _values.push_back(val_ss.str()); 91 break; 92 break; 93 default: 94 throw ParamException("Unsupported parameter type for '" + flag + "'"); 95 } 96} 97 98std::string ParamConfig::flagName(const ASTString& flag_input) { 99 std::stringstream flag_ss; 100 if (!flag_input.beginsWith("-")) { 101 flag_ss << "--"; 102 } 103 flag_ss << flag_input; 104 return flag_ss.str(); 105} 106 107std::string ParamConfig::modelToString(Model& model) { 108 std::stringstream ss; 109 for (auto& i : model) { 110 if (auto* ai = i->dynamicCast<AssignI>()) { 111 auto flag = ParamConfig::flagName(ai->id()); 112 auto* e = ai->e(); 113 switch (e->eid()) { 114 case Expression::E_ARRAYLIT: { 115 auto* al = e->cast<ArrayLit>(); 116 for (auto* exp : al->getVec()) { 117 ss << " " << flag; 118 ss << " " << exp; 119 } 120 break; 121 } 122 case Expression::E_BOOLLIT: 123 if (e->cast<BoolLit>()->v()) { 124 ss << " " << flag; 125 } 126 break; 127 case Expression::E_STRINGLIT: 128 ss << " " << flag; 129 ss << " " << ai->e()->cast<StringLit>()->v(); 130 break; 131 case Expression::E_INTLIT: 132 ss << " " << flag; 133 ss << " " << ai->e()->cast<IntLit>()->v(); 134 break; 135 case Expression::E_FLOATLIT: 136 ss << " " << flag; 137 ss << " " << ai->e()->cast<FloatLit>()->v(); 138 break; 139 default: 140 throw ParamException("Unsupported parameter type for '" + flag + "'"); 141 } 142 } else if (auto* ii = i->dynamicCast<IncludeI>()) { 143 ss << " " << ParamConfig::flagName(ii->f()); 144 ss << " \"" << Printer::escapeStringLit(modelToString(*(ii->m()))) << "\""; 145 } 146 } 147 return ss.str().substr(1); 148} 149 150const std::vector<std::string>& ParamConfig::argv() { return _values; } 151 152void ParamConfig::blacklist(const std::string& disallowed) { _blacklist.insert(disallowed); } 153 154void ParamConfig::blacklist(const std::vector<std::string>& disallowed) { 155 for (const auto& param : disallowed) { 156 _blacklist.insert(param); 157 } 158} 159 160void ParamConfig::negatedFlag(const std::string& flag, const std::string& negated) { 161 _boolSwitches.insert(std::make_pair(flag, negated)); 162} 163 164} // namespace MiniZinc